forked from jbagg/QtZeroConf
Update Bonjour sdk from 333 to 878.200.35
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1156
bonjour-sdk/dns_sd.h
1156
bonjour-sdk/dns_sd.h
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
|
* Copyright (c) 2004-2018 Apple Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
*
|
||||||
@ -31,10 +31,6 @@
|
|||||||
|
|
||||||
#include "dns_sd.h"
|
#include "dns_sd.h"
|
||||||
|
|
||||||
#if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
|
|
||||||
#pragma export on
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// disable warning "conversion from <data> to uint16_t"
|
// disable warning "conversion from <data> to uint16_t"
|
||||||
#pragma warning(disable:4244)
|
#pragma warning(disable:4244)
|
||||||
@ -43,10 +39,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* Supporting Functions
|
* Supporting Functions
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
#define mDNSIsDigit(X) ((X) >= '0' && (X) <= '9')
|
#define mDNSIsDigit(X) ((X) >= '0' && (X) <= '9')
|
||||||
|
|
||||||
@ -54,313 +50,321 @@
|
|||||||
// (DNSServiceConstructFullName depends this returning 1 for true, rather than any non-zero value meaning true)
|
// (DNSServiceConstructFullName depends this returning 1 for true, rather than any non-zero value meaning true)
|
||||||
|
|
||||||
static int DomainEndsInDot(const char *dom)
|
static int DomainEndsInDot(const char *dom)
|
||||||
{
|
{
|
||||||
while (dom[0] && dom[1])
|
while (dom[0] && dom[1])
|
||||||
{
|
{
|
||||||
if (dom[0] == '\\') // advance past escaped byte sequence
|
if (dom[0] == '\\') // advance past escaped byte sequence
|
||||||
{
|
{
|
||||||
if (mDNSIsDigit(dom[1]) && mDNSIsDigit(dom[2]) && mDNSIsDigit(dom[3]))
|
if (mDNSIsDigit(dom[1]) && mDNSIsDigit(dom[2]) && mDNSIsDigit(dom[3]))
|
||||||
dom += 4; // If "\ddd" then skip four
|
dom += 4; // If "\ddd" then skip four
|
||||||
else dom += 2; // else if "\x" then skip two
|
else dom += 2; // else if "\x" then skip two
|
||||||
}
|
}
|
||||||
else dom++; // else goto next character
|
else dom++; // else goto next character
|
||||||
}
|
}
|
||||||
return (dom[0] == '.');
|
return (dom[0] == '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t *InternalTXTRecordSearch
|
static uint8_t *InternalTXTRecordSearch
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord,
|
const void *txtRecord,
|
||||||
const char *key,
|
const char *key,
|
||||||
unsigned long *keylen
|
unsigned long *keylen
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint8_t *p = (uint8_t*)txtRecord;
|
uint8_t *p = (uint8_t*)txtRecord;
|
||||||
uint8_t *e = p + txtLen;
|
uint8_t *e = p + txtLen;
|
||||||
*keylen = (unsigned long) strlen(key);
|
*keylen = (unsigned long) strlen(key);
|
||||||
while (p<e)
|
while (p<e)
|
||||||
{
|
{
|
||||||
uint8_t *x = p;
|
uint8_t *x = p;
|
||||||
p += 1 + p[0];
|
p += 1 + p[0];
|
||||||
if (p <= e && *keylen <= x[0] && !strncasecmp(key, (char*)x+1, *keylen))
|
if (p <= e && *keylen <= x[0] && !strncasecmp(key, (char*)x+1, *keylen))
|
||||||
if (*keylen == x[0] || x[1+*keylen] == '=') return(x);
|
if (*keylen == x[0] || x[1+*keylen] == '=') return(x);
|
||||||
}
|
}
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* General Utility Functions
|
* General Utility Functions
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
// Note: Need to make sure we don't write more than kDNSServiceMaxDomainName (1009) bytes to fullName
|
// Note: Need to make sure we don't write more than kDNSServiceMaxDomainName (1009) bytes to fullName
|
||||||
// In earlier builds this constant was defined to be 1005, so to avoid buffer overruns on clients
|
// In earlier builds this constant was defined to be 1005, so to avoid buffer overruns on clients
|
||||||
// compiled with that constant we'll actually limit the output to 1005 bytes.
|
// compiled with that constant we'll actually limit the output to 1005 bytes.
|
||||||
|
|
||||||
DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
|
DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
|
||||||
(
|
(
|
||||||
char *const fullName,
|
char *const fullName,
|
||||||
const char *const service, // May be NULL
|
const char *const service, // May be NULL
|
||||||
const char *const regtype,
|
const char *const regtype,
|
||||||
const char *const domain
|
const char *const domain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const size_t len = !regtype ? 0 : strlen(regtype) - DomainEndsInDot(regtype);
|
const size_t len = !regtype ? 0 : strlen(regtype) - DomainEndsInDot(regtype);
|
||||||
char *fn = fullName;
|
char *fn = fullName;
|
||||||
char *const lim = fullName + 1005;
|
char *const lim = fullName + 1005;
|
||||||
const char *s = service;
|
const char *s = service;
|
||||||
const char *r = regtype;
|
const char *r = regtype;
|
||||||
const char *d = domain;
|
const char *d = domain;
|
||||||
|
|
||||||
// regtype must be at least "x._udp" or "x._tcp"
|
// regtype must be at least "x._udp" or "x._tcp"
|
||||||
if (len < 6 || !domain || !domain[0]) return kDNSServiceErr_BadParam;
|
if (len < 6 || !domain || !domain[0]) return kDNSServiceErr_BadParam;
|
||||||
if (strncasecmp((regtype + len - 4), "_tcp", 4) && strncasecmp((regtype + len - 4), "_udp", 4)) return kDNSServiceErr_BadParam;
|
if (strncasecmp((regtype + len - 4), "_tcp", 4) && strncasecmp((regtype + len - 4), "_udp", 4)) return kDNSServiceErr_BadParam;
|
||||||
|
|
||||||
if (service && *service)
|
if (service && *service)
|
||||||
{
|
{
|
||||||
while (*s)
|
while (*s)
|
||||||
{
|
{
|
||||||
unsigned char c = *s++; // Needs to be unsigned, or values like 0xFF will be interpreted as < 32
|
unsigned char c = *s++; // Needs to be unsigned, or values like 0xFF will be interpreted as < 32
|
||||||
if (c <= ' ') // Escape non-printable characters
|
if (c <= ' ') // Escape non-printable characters
|
||||||
{
|
{
|
||||||
if (fn+4 >= lim) goto fail;
|
if (fn+4 >= lim) goto fail;
|
||||||
*fn++ = '\\';
|
*fn++ = '\\';
|
||||||
*fn++ = '0' + (c / 100);
|
*fn++ = '0' + (c / 100);
|
||||||
*fn++ = '0' + (c / 10) % 10;
|
*fn++ = '0' + (c / 10) % 10;
|
||||||
c = '0' + (c ) % 10;
|
c = '0' + (c ) % 10;
|
||||||
}
|
}
|
||||||
else if (c == '.' || (c == '\\')) // Escape dot and backslash literals
|
else if (c == '.' || (c == '\\')) // Escape dot and backslash literals
|
||||||
{
|
{
|
||||||
if (fn+2 >= lim) goto fail;
|
if (fn+2 >= lim) goto fail;
|
||||||
*fn++ = '\\';
|
*fn++ = '\\';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (fn+1 >= lim) goto fail;
|
if (fn+1 >= lim) goto fail;
|
||||||
*fn++ = (char)c;
|
*fn++ = (char)c;
|
||||||
}
|
}
|
||||||
*fn++ = '.';
|
*fn++ = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*r) if (fn+1 >= lim) goto fail; else *fn++ = *r++;
|
while (*r) if (fn+1 >= lim) goto fail;else *fn++ = *r++;
|
||||||
if (!DomainEndsInDot(regtype)) { if (fn+1 >= lim) goto fail; else *fn++ = '.'; }
|
if (!DomainEndsInDot(regtype)) { if (fn+1 >= lim) goto fail;else *fn++ = '.';}
|
||||||
|
|
||||||
while (*d) if (fn+1 >= lim) goto fail; else *fn++ = *d++;
|
while (*d) if (fn+1 >= lim) goto fail;else *fn++ = *d++;
|
||||||
if (!DomainEndsInDot(domain)) { if (fn+1 >= lim) goto fail; else *fn++ = '.'; }
|
if (!DomainEndsInDot(domain)) { if (fn+1 >= lim) goto fail;else *fn++ = '.';}
|
||||||
|
|
||||||
*fn = '\0';
|
*fn = '\0';
|
||||||
return kDNSServiceErr_NoError;
|
return kDNSServiceErr_NoError;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
*fn = '\0';
|
*fn = '\0';
|
||||||
return kDNSServiceErr_BadParam;
|
return kDNSServiceErr_BadParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* TXT Record Construction Functions
|
* TXT Record Construction Functions
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
typedef struct _TXTRecordRefRealType
|
typedef struct _TXTRecordRefRealType
|
||||||
{
|
{
|
||||||
uint8_t *buffer; // Pointer to data
|
uint8_t *buffer; // Pointer to data
|
||||||
uint16_t buflen; // Length of buffer
|
uint16_t buflen; // Length of buffer
|
||||||
uint16_t datalen; // Length currently in use
|
uint16_t datalen; // Length currently in use
|
||||||
uint16_t malloced; // Non-zero if buffer was allocated via malloc()
|
uint16_t malloced; // Non-zero if buffer was allocated via malloc()
|
||||||
} TXTRecordRefRealType;
|
} TXTRecordRefRealType;
|
||||||
|
|
||||||
#define txtRec ((TXTRecordRefRealType*)txtRecord)
|
#define txtRec ((TXTRecordRefRealType*)txtRecord)
|
||||||
|
|
||||||
// The opaque storage defined in the public dns_sd.h header is 16 bytes;
|
// The opaque storage defined in the public dns_sd.h header is 16 bytes;
|
||||||
// make sure we don't exceed that.
|
// make sure we don't exceed that.
|
||||||
struct CompileTimeAssertionCheck_dnssd_clientlib
|
struct CompileTimeAssertionCheck_dnssd_clientlib
|
||||||
{
|
{
|
||||||
char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
|
char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
|
||||||
};
|
};
|
||||||
|
|
||||||
void DNSSD_API TXTRecordCreate
|
void DNSSD_API TXTRecordCreate
|
||||||
(
|
(
|
||||||
TXTRecordRef *txtRecord,
|
TXTRecordRef *txtRecord,
|
||||||
uint16_t bufferLen,
|
uint16_t bufferLen,
|
||||||
void *buffer
|
void *buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
txtRec->buffer = buffer;
|
txtRec->buffer = buffer;
|
||||||
txtRec->buflen = buffer ? bufferLen : (uint16_t)0;
|
txtRec->buflen = buffer ? bufferLen : (uint16_t)0;
|
||||||
txtRec->datalen = 0;
|
txtRec->datalen = 0;
|
||||||
txtRec->malloced = 0;
|
txtRec->malloced = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSSD_API TXTRecordDeallocate(TXTRecordRef *txtRecord)
|
void DNSSD_API TXTRecordDeallocate(TXTRecordRef *txtRecord)
|
||||||
{
|
{
|
||||||
if (txtRec->malloced) free(txtRec->buffer);
|
if (txtRec->malloced) free(txtRec->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
DNSServiceErrorType DNSSD_API TXTRecordSetValue
|
DNSServiceErrorType DNSSD_API TXTRecordSetValue
|
||||||
(
|
(
|
||||||
TXTRecordRef *txtRecord,
|
TXTRecordRef *txtRecord,
|
||||||
const char *key,
|
const char *key,
|
||||||
uint8_t valueSize,
|
uint8_t valueSize,
|
||||||
const void *value
|
const void *value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint8_t *start, *p;
|
uint8_t *start, *p;
|
||||||
const char *k;
|
const char *k;
|
||||||
unsigned long keysize, keyvalsize;
|
unsigned long keysize, keyvalsize;
|
||||||
|
|
||||||
for (k = key; *k; k++) if (*k < 0x20 || *k > 0x7E || *k == '=') return(kDNSServiceErr_Invalid);
|
for (k = key; *k; k++) if (*k < 0x20 || *k > 0x7E || *k == '=') return(kDNSServiceErr_Invalid);
|
||||||
keysize = (unsigned long)(k - key);
|
keysize = (unsigned long)(k - key);
|
||||||
keyvalsize = 1 + keysize + (value ? (1 + valueSize) : 0);
|
keyvalsize = 1 + keysize + (value ? (1 + valueSize) : 0);
|
||||||
if (keysize < 1 || keyvalsize > 255) return(kDNSServiceErr_Invalid);
|
if (keysize < 1 || keyvalsize > 255) return(kDNSServiceErr_Invalid);
|
||||||
(void)TXTRecordRemoveValue(txtRecord, key);
|
(void)TXTRecordRemoveValue(txtRecord, key);
|
||||||
if (txtRec->datalen + keyvalsize > txtRec->buflen)
|
if (txtRec->datalen + keyvalsize > txtRec->buflen)
|
||||||
{
|
{
|
||||||
unsigned char *newbuf;
|
unsigned char *newbuf;
|
||||||
unsigned long newlen = txtRec->datalen + keyvalsize;
|
unsigned long newlen = txtRec->datalen + keyvalsize;
|
||||||
if (newlen > 0xFFFF) return(kDNSServiceErr_Invalid);
|
if (newlen > 0xFFFF) return(kDNSServiceErr_Invalid);
|
||||||
newbuf = malloc((size_t)newlen);
|
newbuf = malloc((size_t)newlen);
|
||||||
if (!newbuf) return(kDNSServiceErr_NoMemory);
|
if (!newbuf) return(kDNSServiceErr_NoMemory);
|
||||||
memcpy(newbuf, txtRec->buffer, txtRec->datalen);
|
memcpy(newbuf, txtRec->buffer, txtRec->datalen);
|
||||||
if (txtRec->malloced) free(txtRec->buffer);
|
if (txtRec->malloced) free(txtRec->buffer);
|
||||||
txtRec->buffer = newbuf;
|
txtRec->buffer = newbuf;
|
||||||
txtRec->buflen = (uint16_t)(newlen);
|
txtRec->buflen = (uint16_t)(newlen);
|
||||||
txtRec->malloced = 1;
|
txtRec->malloced = 1;
|
||||||
}
|
}
|
||||||
start = txtRec->buffer + txtRec->datalen;
|
start = txtRec->buffer + txtRec->datalen;
|
||||||
p = start + 1;
|
p = start + 1;
|
||||||
memcpy(p, key, keysize);
|
memcpy(p, key, keysize);
|
||||||
p += keysize;
|
p += keysize;
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
*p++ = '=';
|
*p++ = '=';
|
||||||
memcpy(p, value, valueSize);
|
memcpy(p, value, valueSize);
|
||||||
p += valueSize;
|
p += valueSize;
|
||||||
}
|
}
|
||||||
*start = (uint8_t)(p - start - 1);
|
*start = (uint8_t)(p - start - 1);
|
||||||
txtRec->datalen += p - start;
|
txtRec->datalen += p - start;
|
||||||
return(kDNSServiceErr_NoError);
|
return(kDNSServiceErr_NoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
|
DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
|
||||||
(
|
(
|
||||||
TXTRecordRef *txtRecord,
|
TXTRecordRef *txtRecord,
|
||||||
const char *key
|
const char *key
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned long keylen, itemlen, remainder;
|
unsigned long keylen, itemlen, remainder;
|
||||||
uint8_t *item = InternalTXTRecordSearch(txtRec->datalen, txtRec->buffer, key, &keylen);
|
uint8_t *item = InternalTXTRecordSearch(txtRec->datalen, txtRec->buffer, key, &keylen);
|
||||||
if (!item) return(kDNSServiceErr_NoSuchKey);
|
if (!item) return(kDNSServiceErr_NoSuchKey);
|
||||||
itemlen = (unsigned long)(1 + item[0]);
|
itemlen = (unsigned long)(1 + item[0]);
|
||||||
remainder = (unsigned long)((txtRec->buffer + txtRec->datalen) - (item + itemlen));
|
remainder = (unsigned long)((txtRec->buffer + txtRec->datalen) - (item + itemlen));
|
||||||
// Use memmove because memcpy behaviour is undefined for overlapping regions
|
// Use memmove because memcpy behaviour is undefined for overlapping regions
|
||||||
memmove(item, item + itemlen, remainder);
|
memmove(item, item + itemlen, remainder);
|
||||||
txtRec->datalen -= itemlen;
|
txtRec->datalen -= itemlen;
|
||||||
return(kDNSServiceErr_NoError);
|
return(kDNSServiceErr_NoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t DNSSD_API TXTRecordGetLength (const TXTRecordRef *txtRecord) { return(txtRec->datalen); }
|
uint16_t DNSSD_API TXTRecordGetLength (const TXTRecordRef *txtRecord) { return(txtRec->datalen); }
|
||||||
const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return(txtRec->buffer); }
|
const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return(txtRec->buffer); }
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* TXT Record Parsing Functions
|
* TXT Record Parsing Functions
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
int DNSSD_API TXTRecordContainsKey
|
int DNSSD_API TXTRecordContainsKey
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord,
|
const void *txtRecord,
|
||||||
const char *key
|
const char *key
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned long keylen;
|
unsigned long keylen;
|
||||||
return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
|
return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const void * DNSSD_API TXTRecordGetValuePtr
|
const void * DNSSD_API TXTRecordGetValuePtr
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord,
|
const void *txtRecord,
|
||||||
const char *key,
|
const char *key,
|
||||||
uint8_t *valueLen
|
uint8_t *valueLen
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned long keylen;
|
unsigned long keylen;
|
||||||
uint8_t *item = InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen);
|
uint8_t *item = InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen);
|
||||||
if (!item || item[0] <= keylen) return(NULL); // If key not found, or found with no value, return NULL
|
if (!item || item[0] <= keylen) return(NULL); // If key not found, or found with no value, return NULL
|
||||||
*valueLen = (uint8_t)(item[0] - (keylen + 1));
|
*valueLen = (uint8_t)(item[0] - (keylen + 1));
|
||||||
return (item + 1 + keylen + 1);
|
return (item + 1 + keylen + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t DNSSD_API TXTRecordGetCount
|
uint16_t DNSSD_API TXTRecordGetCount
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord
|
const void *txtRecord
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint16_t count = 0;
|
uint16_t count = 0;
|
||||||
uint8_t *p = (uint8_t*)txtRecord;
|
uint8_t *p = (uint8_t*)txtRecord;
|
||||||
uint8_t *e = p + txtLen;
|
uint8_t *e = p + txtLen;
|
||||||
while (p<e) { p += 1 + p[0]; count++; }
|
while (p<e) { p += 1 + p[0]; count++; }
|
||||||
return((p>e) ? (uint16_t)0 : count);
|
return((p>e) ? (uint16_t)0 : count);
|
||||||
}
|
}
|
||||||
|
|
||||||
DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
|
DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord,
|
const void *txtRecord,
|
||||||
uint16_t itemIndex,
|
uint16_t itemIndex,
|
||||||
uint16_t keyBufLen,
|
uint16_t keyBufLen,
|
||||||
char *key,
|
char *key,
|
||||||
uint8_t *valueLen,
|
uint8_t *valueLen,
|
||||||
const void **value
|
const void **value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint16_t count = 0;
|
uint16_t count = 0;
|
||||||
uint8_t *p = (uint8_t*)txtRecord;
|
uint8_t *p = (uint8_t*)txtRecord;
|
||||||
uint8_t *e = p + txtLen;
|
uint8_t *e = p + txtLen;
|
||||||
while (p<e && count<itemIndex) { p += 1 + p[0]; count++; } // Find requested item
|
while (p<e && count<itemIndex) { p += 1 + p[0]; count++; } // Find requested item
|
||||||
if (p<e && p + 1 + p[0] <= e) // If valid
|
if (p<e && p + 1 + p[0] <= e) // If valid
|
||||||
{
|
{
|
||||||
uint8_t *x = p+1;
|
uint8_t *x = p+1;
|
||||||
unsigned long len = 0;
|
unsigned long len = 0;
|
||||||
e = p + 1 + p[0];
|
e = p + 1 + p[0];
|
||||||
while (x+len<e && x[len] != '=') len++;
|
while (x+len<e && x[len] != '=') len++;
|
||||||
if (len >= keyBufLen) return(kDNSServiceErr_NoMemory);
|
if (len >= keyBufLen) return(kDNSServiceErr_NoMemory);
|
||||||
memcpy(key, x, len);
|
memcpy(key, x, len);
|
||||||
key[len] = 0;
|
key[len] = 0;
|
||||||
if (x+len<e) // If we found '='
|
if (x+len<e) // If we found '='
|
||||||
{
|
{
|
||||||
*value = x + len + 1;
|
*value = x + len + 1;
|
||||||
*valueLen = (uint8_t)(p[0] - (len + 1));
|
*valueLen = (uint8_t)(p[0] - (len + 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*value = NULL;
|
*value = NULL;
|
||||||
*valueLen = 0;
|
*valueLen = 0;
|
||||||
}
|
}
|
||||||
return(kDNSServiceErr_NoError);
|
return(kDNSServiceErr_NoError);
|
||||||
}
|
}
|
||||||
return(kDNSServiceErr_Invalid);
|
return(kDNSServiceErr_Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* SCCS-compatible version string
|
* SCCS-compatible version string
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
// For convenience when using the "strings" command, this is the last thing in the file
|
// For convenience when using the "strings" command, this is the last thing in the file
|
||||||
|
|
||||||
// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
|
// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
|
||||||
// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
|
// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
|
||||||
// To expand "version" to its value before making the string, use STRINGIFY(version) instead
|
// To expand "version" to its value before making the string, use STRINGIFY(version) instead
|
||||||
#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
|
#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) # s
|
||||||
#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
|
#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
|
||||||
|
|
||||||
|
// The "used" variable attribute prevents a non-exported variable from being stripped, even if its visibility is hidden,
|
||||||
|
// e.g., when compiling with -fvisibility=hidden.
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define DNSSD_USED __attribute__((used))
|
||||||
|
#else
|
||||||
|
#define DNSSD_USED
|
||||||
|
#endif
|
||||||
|
|
||||||
// NOT static -- otherwise the compiler may optimize it out
|
// NOT static -- otherwise the compiler may optimize it out
|
||||||
// The "@(#) " pattern is a special prefix the "what" command looks for
|
// The "@(#) " pattern is a special prefix the "what" command looks for
|
||||||
const char VersionString_SCCS_libdnssd[] = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
|
const char VersionString_SCCS_libdnssd[] DNSSD_USED = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
* Copyright (c) 2003-2011 Apple Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
*
|
||||||
@ -31,131 +31,131 @@
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
|
||||||
char *win32_strerror(int inErrorCode)
|
char *win32_strerror(int inErrorCode)
|
||||||
{
|
{
|
||||||
static char buffer[1024];
|
static char buffer[1024];
|
||||||
DWORD n;
|
DWORD n;
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
n = FormatMessageA(
|
n = FormatMessageA(
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL,
|
NULL,
|
||||||
(DWORD) inErrorCode,
|
(DWORD) inErrorCode,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
buffer,
|
buffer,
|
||||||
sizeof(buffer),
|
sizeof(buffer),
|
||||||
NULL);
|
NULL);
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
{
|
{
|
||||||
// Remove any trailing CR's or LF's since some messages have them.
|
// Remove any trailing CR's or LF's since some messages have them.
|
||||||
while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
|
while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
|
||||||
buffer[--n] = '\0';
|
buffer[--n] = '\0';
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void put_uint32(const uint32_t l, char **ptr)
|
void put_uint32(const uint32_t l, char **ptr)
|
||||||
{
|
{
|
||||||
(*ptr)[0] = (char)((l >> 24) & 0xFF);
|
(*ptr)[0] = (char)((l >> 24) & 0xFF);
|
||||||
(*ptr)[1] = (char)((l >> 16) & 0xFF);
|
(*ptr)[1] = (char)((l >> 16) & 0xFF);
|
||||||
(*ptr)[2] = (char)((l >> 8) & 0xFF);
|
(*ptr)[2] = (char)((l >> 8) & 0xFF);
|
||||||
(*ptr)[3] = (char)((l ) & 0xFF);
|
(*ptr)[3] = (char)((l ) & 0xFF);
|
||||||
*ptr += sizeof(uint32_t);
|
*ptr += sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_uint32(const char **ptr, const char *end)
|
uint32_t get_uint32(const char **ptr, const char *end)
|
||||||
{
|
{
|
||||||
if (!*ptr || *ptr + sizeof(uint32_t) > end)
|
if (!*ptr || *ptr + sizeof(uint32_t) > end)
|
||||||
{
|
{
|
||||||
*ptr = NULL;
|
*ptr = NULL;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t *p = (uint8_t*) *ptr;
|
uint8_t *p = (uint8_t*) *ptr;
|
||||||
*ptr += sizeof(uint32_t);
|
*ptr += sizeof(uint32_t);
|
||||||
return((uint32_t) ((uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]));
|
return((uint32_t) ((uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void put_uint16(uint16_t s, char **ptr)
|
void put_uint16(uint16_t s, char **ptr)
|
||||||
{
|
{
|
||||||
(*ptr)[0] = (char)((s >> 8) & 0xFF);
|
(*ptr)[0] = (char)((s >> 8) & 0xFF);
|
||||||
(*ptr)[1] = (char)((s ) & 0xFF);
|
(*ptr)[1] = (char)((s ) & 0xFF);
|
||||||
*ptr += sizeof(uint16_t);
|
*ptr += sizeof(uint16_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t get_uint16(const char **ptr, const char *end)
|
uint16_t get_uint16(const char **ptr, const char *end)
|
||||||
{
|
{
|
||||||
if (!*ptr || *ptr + sizeof(uint16_t) > end)
|
if (!*ptr || *ptr + sizeof(uint16_t) > end)
|
||||||
{
|
{
|
||||||
*ptr = NULL;
|
*ptr = NULL;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t *p = (uint8_t*) *ptr;
|
uint8_t *p = (uint8_t*) *ptr;
|
||||||
*ptr += sizeof(uint16_t);
|
*ptr += sizeof(uint16_t);
|
||||||
return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
|
return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int put_string(const char *str, char **ptr)
|
int put_string(const char *str, char **ptr)
|
||||||
{
|
{
|
||||||
if (!str) str = "";
|
if (!str) str = "";
|
||||||
strcpy(*ptr, str);
|
strcpy(*ptr, str);
|
||||||
*ptr += strlen(str) + 1;
|
*ptr += strlen(str) + 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_string(const char **ptr, const char *const end, char *buffer, int buflen)
|
int get_string(const char **ptr, const char *const end, char *buffer, int buflen)
|
||||||
{
|
{
|
||||||
if (!*ptr)
|
if (!*ptr)
|
||||||
{
|
{
|
||||||
*buffer = 0;
|
*buffer = 0;
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *lim = buffer + buflen; // Calculate limit
|
char *lim = buffer + buflen; // Calculate limit
|
||||||
while (*ptr < end && buffer < lim)
|
while (*ptr < end && buffer < lim)
|
||||||
{
|
{
|
||||||
char c = *buffer++ = *(*ptr)++;
|
char c = *buffer++ = *(*ptr)++;
|
||||||
if (c == 0) return(0); // Success
|
if (c == 0) return(0); // Success
|
||||||
}
|
}
|
||||||
if (buffer == lim) buffer--;
|
if (buffer == lim) buffer--;
|
||||||
*buffer = 0; // Failed, so terminate string,
|
*buffer = 0; // Failed, so terminate string,
|
||||||
*ptr = NULL; // clear pointer,
|
*ptr = NULL; // clear pointer,
|
||||||
return(-1); // and return failure indication
|
return(-1); // and return failure indication
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr)
|
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr)
|
||||||
{
|
{
|
||||||
memcpy(*ptr, rdata, rdlen);
|
memcpy(*ptr, rdata, rdlen);
|
||||||
*ptr += rdlen;
|
*ptr += rdlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_rdata(const char **ptr, const char *end, int rdlen)
|
const char *get_rdata(const char **ptr, const char *end, int rdlen)
|
||||||
{
|
{
|
||||||
if (!*ptr || *ptr + rdlen > end)
|
if (!*ptr || *ptr + rdlen > end)
|
||||||
{
|
{
|
||||||
*ptr = NULL;
|
*ptr = NULL;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *rd = *ptr;
|
const char *rd = *ptr;
|
||||||
*ptr += rdlen;
|
*ptr += rdlen;
|
||||||
return rd;
|
return rd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvertHeaderBytes(ipc_msg_hdr *hdr)
|
void ConvertHeaderBytes(ipc_msg_hdr *hdr)
|
||||||
{
|
{
|
||||||
hdr->version = htonl(hdr->version);
|
hdr->version = htonl(hdr->version);
|
||||||
hdr->datalen = htonl(hdr->datalen);
|
hdr->datalen = htonl(hdr->datalen);
|
||||||
hdr->ipc_flags = htonl(hdr->ipc_flags);
|
hdr->ipc_flags = htonl(hdr->ipc_flags);
|
||||||
hdr->op = htonl(hdr->op );
|
hdr->op = htonl(hdr->op );
|
||||||
hdr->reg_index = htonl(hdr->reg_index);
|
hdr->reg_index = htonl(hdr->reg_index);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
* Copyright (c) 2003-2015 Apple Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
*
|
||||||
@ -35,72 +35,72 @@
|
|||||||
// Common cross platform services
|
// Common cross platform services
|
||||||
//
|
//
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# define dnssd_InvalidSocket INVALID_SOCKET
|
# define dnssd_InvalidSocket INVALID_SOCKET
|
||||||
# define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
|
# define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
|
||||||
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
|
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
# define dnssd_EINTR WSAEINTR
|
# define dnssd_EINTR WSAEINTR
|
||||||
# define dnssd_ECONNRESET WSAECONNRESET
|
# define dnssd_ECONNRESET WSAECONNRESET
|
||||||
# define dnssd_sock_t SOCKET
|
# define dnssd_socklen_t int
|
||||||
# define dnssd_socklen_t int
|
# define dnssd_close(sock) closesocket(sock)
|
||||||
# define dnssd_close(sock) closesocket(sock)
|
# define dnssd_errno WSAGetLastError()
|
||||||
# define dnssd_errno WSAGetLastError()
|
# define dnssd_strerror(X) win32_strerror(X)
|
||||||
# define dnssd_strerror(X) win32_strerror(X)
|
# define ssize_t int
|
||||||
# define ssize_t int
|
# define getpid _getpid
|
||||||
# define getpid _getpid
|
# define unlink _unlink
|
||||||
# define unlink _unlink
|
|
||||||
extern char *win32_strerror(int inErrorCode);
|
extern char *win32_strerror(int inErrorCode);
|
||||||
#else
|
#else
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <sys/un.h>
|
# include <sys/un.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
# define dnssd_InvalidSocket -1
|
# include <arpa/inet.h>
|
||||||
# define dnssd_SocketValid(s) ((s) >= 0)
|
# define dnssd_InvalidSocket -1
|
||||||
# define dnssd_EWOULDBLOCK EWOULDBLOCK
|
# define dnssd_SocketValid(s) ((s) >= 0)
|
||||||
# define dnssd_EINTR EINTR
|
# define dnssd_EWOULDBLOCK EWOULDBLOCK
|
||||||
# define dnssd_ECONNRESET ECONNRESET
|
# define dnssd_EINTR EINTR
|
||||||
# define dnssd_EPIPE EPIPE
|
# define dnssd_ECONNRESET ECONNRESET
|
||||||
# define dnssd_sock_t int
|
# define dnssd_EPIPE EPIPE
|
||||||
# define dnssd_socklen_t unsigned int
|
# define dnssd_socklen_t unsigned int
|
||||||
# define dnssd_close(sock) close(sock)
|
# define dnssd_close(sock) close(sock)
|
||||||
# define dnssd_errno errno
|
# define dnssd_errno errno
|
||||||
# define dnssd_strerror(X) strerror(X)
|
# define dnssd_strerror(X) strerror(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_TCP_LOOPBACK)
|
#if defined(USE_TCP_LOOPBACK)
|
||||||
# define AF_DNSSD AF_INET
|
# define AF_DNSSD AF_INET
|
||||||
# define MDNS_TCP_SERVERADDR "127.0.0.1"
|
# define MDNS_TCP_SERVERADDR "127.0.0.1"
|
||||||
# define MDNS_TCP_SERVERPORT 5354
|
# define MDNS_TCP_SERVERPORT 5354
|
||||||
# define LISTENQ 5
|
# define LISTENQ 5
|
||||||
# define dnssd_sockaddr_t struct sockaddr_in
|
# define dnssd_sockaddr_t struct sockaddr_in
|
||||||
#else
|
#else
|
||||||
# define AF_DNSSD AF_LOCAL
|
# define AF_DNSSD AF_LOCAL
|
||||||
# ifndef MDNS_UDS_SERVERPATH
|
# ifndef MDNS_UDS_SERVERPATH
|
||||||
# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
|
# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
|
||||||
# endif
|
# endif
|
||||||
# define LISTENQ 100
|
# define MDNS_UDS_SERVERPATH_ENVVAR "DNSSD_UDS_PATH"
|
||||||
// longest legal control path length
|
# define LISTENQ 100
|
||||||
# define MAX_CTLPATH 256
|
// longest legal control path length
|
||||||
# define dnssd_sockaddr_t struct sockaddr_un
|
# define MAX_CTLPATH (sizeof(((struct sockaddr_un*)0)->sun_path))
|
||||||
|
# define dnssd_sockaddr_t struct sockaddr_un
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Compatibility workaround
|
// Compatibility workaround
|
||||||
#ifndef AF_LOCAL
|
#ifndef AF_LOCAL
|
||||||
#define AF_LOCAL AF_UNIX
|
#define AF_LOCAL AF_UNIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// General UDS constants
|
// General UDS constants
|
||||||
#define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record
|
#define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record
|
||||||
|
|
||||||
// IPC data encoding constants and types
|
// IPC data encoding constants and types
|
||||||
#define VERSION 1
|
#define VERSION 1
|
||||||
#define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client
|
#define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client
|
||||||
|
|
||||||
// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
|
// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
|
||||||
// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
|
// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
|
||||||
@ -116,10 +116,10 @@ extern char *win32_strerror(int inErrorCode);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
request_op_none = 0, // No request yet received on this connection
|
request_op_none = 0, // No request yet received on this connection
|
||||||
connection_request = 1, // connected socket via DNSServiceConnect()
|
connection_request = 1, // connected socket via DNSServiceConnect()
|
||||||
reg_record_request, // reg/remove record only valid for connected sockets
|
reg_record_request, // reg/remove record only valid for connected sockets
|
||||||
remove_record_request,
|
remove_record_request,
|
||||||
enumeration_request,
|
enumeration_request,
|
||||||
reg_service_request,
|
reg_service_request,
|
||||||
@ -129,55 +129,58 @@ typedef enum
|
|||||||
reconfirm_record_request,
|
reconfirm_record_request,
|
||||||
add_record_request,
|
add_record_request,
|
||||||
update_record_request,
|
update_record_request,
|
||||||
setdomain_request, // Up to here is in Tiger and B4W 1.0.3
|
setdomain_request, // Up to here is in Tiger and B4W 1.0.3
|
||||||
getproperty_request, // New in B4W 1.0.4
|
getproperty_request, // New in B4W 1.0.4
|
||||||
port_mapping_request, // New in Leopard and B4W 2.0
|
port_mapping_request, // New in Leopard and B4W 2.0
|
||||||
addrinfo_request,
|
addrinfo_request,
|
||||||
send_bpf, // New in SL
|
send_bpf, // New in SL
|
||||||
|
getpid_request,
|
||||||
|
release_request,
|
||||||
|
connection_delegate_request,
|
||||||
|
|
||||||
cancel_request = 63
|
cancel_request = 63
|
||||||
} request_op_t;
|
} request_op_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
enumeration_reply_op = 64,
|
enumeration_reply_op = 64,
|
||||||
reg_service_reply_op,
|
reg_service_reply_op,
|
||||||
browse_reply_op,
|
browse_reply_op,
|
||||||
resolve_reply_op,
|
resolve_reply_op,
|
||||||
query_reply_op,
|
query_reply_op,
|
||||||
reg_record_reply_op, // Up to here is in Tiger and B4W 1.0.3
|
reg_record_reply_op, // Up to here is in Tiger and B4W 1.0.3
|
||||||
getproperty_reply_op, // New in B4W 1.0.4
|
getproperty_reply_op, // New in B4W 1.0.4
|
||||||
port_mapping_reply_op, // New in Leopard and B4W 2.0
|
port_mapping_reply_op, // New in Leopard and B4W 2.0
|
||||||
addrinfo_reply_op
|
addrinfo_reply_op
|
||||||
} reply_op_t;
|
} reply_op_t;
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
# pragma pack(push,4)
|
# pragma pack(push,4)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Define context object big enough to hold a 64-bit pointer,
|
// Define context object big enough to hold a 64-bit pointer,
|
||||||
// to accomodate 64-bit clients communicating with 32-bit daemon.
|
// to accomodate 64-bit clients communicating with 32-bit daemon.
|
||||||
// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
|
// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
|
||||||
typedef packedunion
|
typedef packedunion
|
||||||
{
|
{
|
||||||
void *context;
|
void *context;
|
||||||
uint32_t u32[2];
|
uint32_t u32[2];
|
||||||
} client_context_t;
|
} client_context_t;
|
||||||
|
|
||||||
typedef packedstruct
|
typedef packedstruct
|
||||||
{
|
{
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t datalen;
|
uint32_t datalen;
|
||||||
uint32_t ipc_flags;
|
uint32_t ipc_flags;
|
||||||
uint32_t op; // request_op_t or reply_op_t
|
uint32_t op; // request_op_t or reply_op_t
|
||||||
client_context_t client_context; // context passed from client, returned by server in corresponding reply
|
client_context_t client_context; // context passed from client, returned by server in corresponding reply
|
||||||
uint32_t reg_index; // identifier for a record registered via DNSServiceRegisterRecord() on a
|
uint32_t reg_index; // identifier for a record registered via DNSServiceRegisterRecord() on a
|
||||||
// socket connected by DNSServiceCreateConnection(). Must be unique in the scope of the connection, such that and
|
// socket connected by DNSServiceCreateConnection(). Must be unique in the scope of the connection, such that and
|
||||||
// index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord())
|
// index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord())
|
||||||
} ipc_msg_hdr;
|
} ipc_msg_hdr;
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
# pragma pack(pop)
|
# pragma pack(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// routines to write to and extract data from message buffers.
|
// routines to write to and extract data from message buffers.
|
||||||
@ -202,16 +205,16 @@ int get_string(const char **ptr, const char *const end, char *buffer, int buflen
|
|||||||
|
|
||||||
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
|
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
|
||||||
const char *get_rdata(const char **ptr, const char *end, int rdlen); // return value is rdata pointed to by *ptr -
|
const char *get_rdata(const char **ptr, const char *end, int rdlen); // return value is rdata pointed to by *ptr -
|
||||||
// rdata is not copied from buffer.
|
// rdata is not copied from buffer.
|
||||||
|
|
||||||
void ConvertHeaderBytes(ipc_msg_hdr *hdr);
|
void ConvertHeaderBytes(ipc_msg_hdr *hdr);
|
||||||
|
|
||||||
struct CompileTimeAssertionChecks_dnssd_ipc
|
struct CompileTimeAssertionChecks_dnssd_ipc
|
||||||
{
|
{
|
||||||
// Check that the compiler generated our on-the-wire packet format structure definitions
|
// Check that the compiler generated our on-the-wire packet format structure definitions
|
||||||
// properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
|
// properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
|
||||||
char assert0[(sizeof(client_context_t) == 8) ? 1 : -1];
|
char assert0[(sizeof(client_context_t) == 8) ? 1 : -1];
|
||||||
char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1];
|
char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DNSSD_IPC_H
|
#endif // DNSSD_IPC_H
|
||||||
|
Reference in New Issue
Block a user