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
1166
bonjour-sdk/dns_sd.h
1166
bonjour-sdk/dns_sd.h
File diff suppressed because it is too large
Load Diff
@ -1,28 +1,28 @@
|
||||
/* -*- 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:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 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
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
@ -31,22 +31,18 @@
|
||||
|
||||
#include "dns_sd.h"
|
||||
|
||||
#if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
|
||||
#pragma export on
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
// disable warning "conversion from <data> to uint16_t"
|
||||
#pragma warning(disable:4244)
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************
|
||||
*
|
||||
* Supporting Functions
|
||||
*
|
||||
*********************************************************************************************/
|
||||
*
|
||||
* Supporting Functions
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
#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)
|
||||
|
||||
static int DomainEndsInDot(const char *dom)
|
||||
{
|
||||
while (dom[0] && dom[1])
|
||||
{
|
||||
if (dom[0] == '\\') // advance past escaped byte sequence
|
||||
{
|
||||
if (mDNSIsDigit(dom[1]) && mDNSIsDigit(dom[2]) && mDNSIsDigit(dom[3]))
|
||||
dom += 4; // If "\ddd" then skip four
|
||||
else dom += 2; // else if "\x" then skip two
|
||||
}
|
||||
else dom++; // else goto next character
|
||||
}
|
||||
return (dom[0] == '.');
|
||||
}
|
||||
{
|
||||
while (dom[0] && dom[1])
|
||||
{
|
||||
if (dom[0] == '\\') // advance past escaped byte sequence
|
||||
{
|
||||
if (mDNSIsDigit(dom[1]) && mDNSIsDigit(dom[2]) && mDNSIsDigit(dom[3]))
|
||||
dom += 4; // If "\ddd" then skip four
|
||||
else dom += 2; // else if "\x" then skip two
|
||||
}
|
||||
else dom++; // else goto next character
|
||||
}
|
||||
return (dom[0] == '.');
|
||||
}
|
||||
|
||||
static uint8_t *InternalTXTRecordSearch
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord,
|
||||
const char *key,
|
||||
unsigned long *keylen
|
||||
)
|
||||
{
|
||||
uint8_t *p = (uint8_t*)txtRecord;
|
||||
uint8_t *e = p + txtLen;
|
||||
*keylen = (unsigned long) strlen(key);
|
||||
while (p<e)
|
||||
{
|
||||
uint8_t *x = p;
|
||||
p += 1 + p[0];
|
||||
if (p <= e && *keylen <= x[0] && !strncasecmp(key, (char*)x+1, *keylen))
|
||||
if (*keylen == x[0] || x[1+*keylen] == '=') return(x);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord,
|
||||
const char *key,
|
||||
unsigned long *keylen
|
||||
)
|
||||
{
|
||||
uint8_t *p = (uint8_t*)txtRecord;
|
||||
uint8_t *e = p + txtLen;
|
||||
*keylen = (unsigned long) strlen(key);
|
||||
while (p<e)
|
||||
{
|
||||
uint8_t *x = p;
|
||||
p += 1 + p[0];
|
||||
if (p <= e && *keylen <= x[0] && !strncasecmp(key, (char*)x+1, *keylen))
|
||||
if (*keylen == x[0] || x[1+*keylen] == '=') return(x);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
*
|
||||
* General Utility Functions
|
||||
*
|
||||
*********************************************************************************************/
|
||||
*
|
||||
* General Utility Functions
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
// 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
|
||||
// compiled with that constant we'll actually limit the output to 1005 bytes.
|
||||
|
||||
DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
|
||||
(
|
||||
char *const fullName,
|
||||
const char *const service, // May be NULL
|
||||
const char *const regtype,
|
||||
const char *const domain
|
||||
)
|
||||
{
|
||||
const size_t len = !regtype ? 0 : strlen(regtype) - DomainEndsInDot(regtype);
|
||||
char *fn = fullName;
|
||||
char *const lim = fullName + 1005;
|
||||
const char *s = service;
|
||||
const char *r = regtype;
|
||||
const char *d = domain;
|
||||
(
|
||||
char *const fullName,
|
||||
const char *const service, // May be NULL
|
||||
const char *const regtype,
|
||||
const char *const domain
|
||||
)
|
||||
{
|
||||
const size_t len = !regtype ? 0 : strlen(regtype) - DomainEndsInDot(regtype);
|
||||
char *fn = fullName;
|
||||
char *const lim = fullName + 1005;
|
||||
const char *s = service;
|
||||
const char *r = regtype;
|
||||
const char *d = domain;
|
||||
|
||||
// regtype must be at least "x._udp" or "x._tcp"
|
||||
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;
|
||||
// regtype must be at least "x._udp" or "x._tcp"
|
||||
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 (service && *service)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
unsigned char c = *s++; // Needs to be unsigned, or values like 0xFF will be interpreted as < 32
|
||||
if (c <= ' ') // Escape non-printable characters
|
||||
{
|
||||
if (fn+4 >= lim) goto fail;
|
||||
*fn++ = '\\';
|
||||
*fn++ = '0' + (c / 100);
|
||||
*fn++ = '0' + (c / 10) % 10;
|
||||
c = '0' + (c ) % 10;
|
||||
}
|
||||
else if (c == '.' || (c == '\\')) // Escape dot and backslash literals
|
||||
{
|
||||
if (fn+2 >= lim) goto fail;
|
||||
*fn++ = '\\';
|
||||
}
|
||||
else
|
||||
if (fn+1 >= lim) goto fail;
|
||||
*fn++ = (char)c;
|
||||
}
|
||||
*fn++ = '.';
|
||||
}
|
||||
if (service && *service)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
unsigned char c = *s++; // Needs to be unsigned, or values like 0xFF will be interpreted as < 32
|
||||
if (c <= ' ') // Escape non-printable characters
|
||||
{
|
||||
if (fn+4 >= lim) goto fail;
|
||||
*fn++ = '\\';
|
||||
*fn++ = '0' + (c / 100);
|
||||
*fn++ = '0' + (c / 10) % 10;
|
||||
c = '0' + (c ) % 10;
|
||||
}
|
||||
else if (c == '.' || (c == '\\')) // Escape dot and backslash literals
|
||||
{
|
||||
if (fn+2 >= lim) goto fail;
|
||||
*fn++ = '\\';
|
||||
}
|
||||
else
|
||||
if (fn+1 >= lim) goto fail;
|
||||
*fn++ = (char)c;
|
||||
}
|
||||
*fn++ = '.';
|
||||
}
|
||||
|
||||
while (*r) if (fn+1 >= lim) goto fail; else *fn++ = *r++;
|
||||
if (!DomainEndsInDot(regtype)) { if (fn+1 >= lim) goto fail; else *fn++ = '.'; }
|
||||
while (*r) if (fn+1 >= lim) goto fail;else *fn++ = *r++;
|
||||
if (!DomainEndsInDot(regtype)) { if (fn+1 >= lim) goto fail;else *fn++ = '.';}
|
||||
|
||||
while (*d) if (fn+1 >= lim) goto fail; else *fn++ = *d++;
|
||||
if (!DomainEndsInDot(domain)) { if (fn+1 >= lim) goto fail; else *fn++ = '.'; }
|
||||
while (*d) if (fn+1 >= lim) goto fail;else *fn++ = *d++;
|
||||
if (!DomainEndsInDot(domain)) { if (fn+1 >= lim) goto fail;else *fn++ = '.';}
|
||||
|
||||
*fn = '\0';
|
||||
return kDNSServiceErr_NoError;
|
||||
*fn = '\0';
|
||||
return kDNSServiceErr_NoError;
|
||||
|
||||
fail:
|
||||
*fn = '\0';
|
||||
return kDNSServiceErr_BadParam;
|
||||
}
|
||||
*fn = '\0';
|
||||
return kDNSServiceErr_BadParam;
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
*
|
||||
* TXT Record Construction Functions
|
||||
*
|
||||
*********************************************************************************************/
|
||||
*
|
||||
* TXT Record Construction Functions
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
typedef struct _TXTRecordRefRealType
|
||||
{
|
||||
uint8_t *buffer; // Pointer to data
|
||||
uint16_t buflen; // Length of buffer
|
||||
uint16_t datalen; // Length currently in use
|
||||
uint16_t malloced; // Non-zero if buffer was allocated via malloc()
|
||||
} TXTRecordRefRealType;
|
||||
{
|
||||
uint8_t *buffer; // Pointer to data
|
||||
uint16_t buflen; // Length of buffer
|
||||
uint16_t datalen; // Length currently in use
|
||||
uint16_t malloced; // Non-zero if buffer was allocated via malloc()
|
||||
} TXTRecordRefRealType;
|
||||
|
||||
#define txtRec ((TXTRecordRefRealType*)txtRecord)
|
||||
|
||||
// The opaque storage defined in the public dns_sd.h header is 16 bytes;
|
||||
// make sure we don't exceed that.
|
||||
struct CompileTimeAssertionCheck_dnssd_clientlib
|
||||
{
|
||||
char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
|
||||
};
|
||||
{
|
||||
char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
|
||||
};
|
||||
|
||||
void DNSSD_API TXTRecordCreate
|
||||
(
|
||||
TXTRecordRef *txtRecord,
|
||||
uint16_t bufferLen,
|
||||
void *buffer
|
||||
)
|
||||
{
|
||||
txtRec->buffer = buffer;
|
||||
txtRec->buflen = buffer ? bufferLen : (uint16_t)0;
|
||||
txtRec->datalen = 0;
|
||||
txtRec->malloced = 0;
|
||||
}
|
||||
(
|
||||
TXTRecordRef *txtRecord,
|
||||
uint16_t bufferLen,
|
||||
void *buffer
|
||||
)
|
||||
{
|
||||
txtRec->buffer = buffer;
|
||||
txtRec->buflen = buffer ? bufferLen : (uint16_t)0;
|
||||
txtRec->datalen = 0;
|
||||
txtRec->malloced = 0;
|
||||
}
|
||||
|
||||
void DNSSD_API TXTRecordDeallocate(TXTRecordRef *txtRecord)
|
||||
{
|
||||
if (txtRec->malloced) free(txtRec->buffer);
|
||||
}
|
||||
{
|
||||
if (txtRec->malloced) free(txtRec->buffer);
|
||||
}
|
||||
|
||||
DNSServiceErrorType DNSSD_API TXTRecordSetValue
|
||||
(
|
||||
TXTRecordRef *txtRecord,
|
||||
const char *key,
|
||||
uint8_t valueSize,
|
||||
const void *value
|
||||
)
|
||||
{
|
||||
uint8_t *start, *p;
|
||||
const char *k;
|
||||
unsigned long keysize, keyvalsize;
|
||||
(
|
||||
TXTRecordRef *txtRecord,
|
||||
const char *key,
|
||||
uint8_t valueSize,
|
||||
const void *value
|
||||
)
|
||||
{
|
||||
uint8_t *start, *p;
|
||||
const char *k;
|
||||
unsigned long keysize, keyvalsize;
|
||||
|
||||
for (k = key; *k; k++) if (*k < 0x20 || *k > 0x7E || *k == '=') return(kDNSServiceErr_Invalid);
|
||||
keysize = (unsigned long)(k - key);
|
||||
keyvalsize = 1 + keysize + (value ? (1 + valueSize) : 0);
|
||||
if (keysize < 1 || keyvalsize > 255) return(kDNSServiceErr_Invalid);
|
||||
(void)TXTRecordRemoveValue(txtRecord, key);
|
||||
if (txtRec->datalen + keyvalsize > txtRec->buflen)
|
||||
{
|
||||
unsigned char *newbuf;
|
||||
unsigned long newlen = txtRec->datalen + keyvalsize;
|
||||
if (newlen > 0xFFFF) return(kDNSServiceErr_Invalid);
|
||||
newbuf = malloc((size_t)newlen);
|
||||
if (!newbuf) return(kDNSServiceErr_NoMemory);
|
||||
memcpy(newbuf, txtRec->buffer, txtRec->datalen);
|
||||
if (txtRec->malloced) free(txtRec->buffer);
|
||||
txtRec->buffer = newbuf;
|
||||
txtRec->buflen = (uint16_t)(newlen);
|
||||
txtRec->malloced = 1;
|
||||
}
|
||||
start = txtRec->buffer + txtRec->datalen;
|
||||
p = start + 1;
|
||||
memcpy(p, key, keysize);
|
||||
p += keysize;
|
||||
if (value)
|
||||
{
|
||||
*p++ = '=';
|
||||
memcpy(p, value, valueSize);
|
||||
p += valueSize;
|
||||
}
|
||||
*start = (uint8_t)(p - start - 1);
|
||||
txtRec->datalen += p - start;
|
||||
return(kDNSServiceErr_NoError);
|
||||
}
|
||||
for (k = key; *k; k++) if (*k < 0x20 || *k > 0x7E || *k == '=') return(kDNSServiceErr_Invalid);
|
||||
keysize = (unsigned long)(k - key);
|
||||
keyvalsize = 1 + keysize + (value ? (1 + valueSize) : 0);
|
||||
if (keysize < 1 || keyvalsize > 255) return(kDNSServiceErr_Invalid);
|
||||
(void)TXTRecordRemoveValue(txtRecord, key);
|
||||
if (txtRec->datalen + keyvalsize > txtRec->buflen)
|
||||
{
|
||||
unsigned char *newbuf;
|
||||
unsigned long newlen = txtRec->datalen + keyvalsize;
|
||||
if (newlen > 0xFFFF) return(kDNSServiceErr_Invalid);
|
||||
newbuf = malloc((size_t)newlen);
|
||||
if (!newbuf) return(kDNSServiceErr_NoMemory);
|
||||
memcpy(newbuf, txtRec->buffer, txtRec->datalen);
|
||||
if (txtRec->malloced) free(txtRec->buffer);
|
||||
txtRec->buffer = newbuf;
|
||||
txtRec->buflen = (uint16_t)(newlen);
|
||||
txtRec->malloced = 1;
|
||||
}
|
||||
start = txtRec->buffer + txtRec->datalen;
|
||||
p = start + 1;
|
||||
memcpy(p, key, keysize);
|
||||
p += keysize;
|
||||
if (value)
|
||||
{
|
||||
*p++ = '=';
|
||||
memcpy(p, value, valueSize);
|
||||
p += valueSize;
|
||||
}
|
||||
*start = (uint8_t)(p - start - 1);
|
||||
txtRec->datalen += p - start;
|
||||
return(kDNSServiceErr_NoError);
|
||||
}
|
||||
|
||||
DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
|
||||
(
|
||||
TXTRecordRef *txtRecord,
|
||||
const char *key
|
||||
)
|
||||
{
|
||||
unsigned long keylen, itemlen, remainder;
|
||||
uint8_t *item = InternalTXTRecordSearch(txtRec->datalen, txtRec->buffer, key, &keylen);
|
||||
if (!item) return(kDNSServiceErr_NoSuchKey);
|
||||
itemlen = (unsigned long)(1 + item[0]);
|
||||
remainder = (unsigned long)((txtRec->buffer + txtRec->datalen) - (item + itemlen));
|
||||
// Use memmove because memcpy behaviour is undefined for overlapping regions
|
||||
memmove(item, item + itemlen, remainder);
|
||||
txtRec->datalen -= itemlen;
|
||||
return(kDNSServiceErr_NoError);
|
||||
}
|
||||
(
|
||||
TXTRecordRef *txtRecord,
|
||||
const char *key
|
||||
)
|
||||
{
|
||||
unsigned long keylen, itemlen, remainder;
|
||||
uint8_t *item = InternalTXTRecordSearch(txtRec->datalen, txtRec->buffer, key, &keylen);
|
||||
if (!item) return(kDNSServiceErr_NoSuchKey);
|
||||
itemlen = (unsigned long)(1 + item[0]);
|
||||
remainder = (unsigned long)((txtRec->buffer + txtRec->datalen) - (item + itemlen));
|
||||
// Use memmove because memcpy behaviour is undefined for overlapping regions
|
||||
memmove(item, item + itemlen, remainder);
|
||||
txtRec->datalen -= itemlen;
|
||||
return(kDNSServiceErr_NoError);
|
||||
}
|
||||
|
||||
uint16_t DNSSD_API TXTRecordGetLength (const TXTRecordRef *txtRecord) { return(txtRec->datalen); }
|
||||
const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return(txtRec->buffer); }
|
||||
|
||||
/*********************************************************************************************
|
||||
*
|
||||
* TXT Record Parsing Functions
|
||||
*
|
||||
*********************************************************************************************/
|
||||
*
|
||||
* TXT Record Parsing Functions
|
||||
*
|
||||
*********************************************************************************************/
|
||||
|
||||
int DNSSD_API TXTRecordContainsKey
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord,
|
||||
const char *key
|
||||
)
|
||||
{
|
||||
unsigned long keylen;
|
||||
return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
|
||||
}
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord,
|
||||
const char *key
|
||||
)
|
||||
{
|
||||
unsigned long keylen;
|
||||
return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
|
||||
}
|
||||
|
||||
const void * DNSSD_API TXTRecordGetValuePtr
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord,
|
||||
const char *key,
|
||||
uint8_t *valueLen
|
||||
)
|
||||
{
|
||||
unsigned long 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
|
||||
*valueLen = (uint8_t)(item[0] - (keylen + 1));
|
||||
return (item + 1 + keylen + 1);
|
||||
}
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord,
|
||||
const char *key,
|
||||
uint8_t *valueLen
|
||||
)
|
||||
{
|
||||
unsigned long 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
|
||||
*valueLen = (uint8_t)(item[0] - (keylen + 1));
|
||||
return (item + 1 + keylen + 1);
|
||||
}
|
||||
|
||||
uint16_t DNSSD_API TXTRecordGetCount
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord
|
||||
)
|
||||
{
|
||||
uint16_t count = 0;
|
||||
uint8_t *p = (uint8_t*)txtRecord;
|
||||
uint8_t *e = p + txtLen;
|
||||
while (p<e) { p += 1 + p[0]; count++; }
|
||||
return((p>e) ? (uint16_t)0 : count);
|
||||
}
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord
|
||||
)
|
||||
{
|
||||
uint16_t count = 0;
|
||||
uint8_t *p = (uint8_t*)txtRecord;
|
||||
uint8_t *e = p + txtLen;
|
||||
while (p<e) { p += 1 + p[0]; count++; }
|
||||
return((p>e) ? (uint16_t)0 : count);
|
||||
}
|
||||
|
||||
DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord,
|
||||
uint16_t itemIndex,
|
||||
uint16_t keyBufLen,
|
||||
char *key,
|
||||
uint8_t *valueLen,
|
||||
const void **value
|
||||
)
|
||||
{
|
||||
uint16_t count = 0;
|
||||
uint8_t *p = (uint8_t*)txtRecord;
|
||||
uint8_t *e = p + txtLen;
|
||||
while (p<e && count<itemIndex) { p += 1 + p[0]; count++; } // Find requested item
|
||||
if (p<e && p + 1 + p[0] <= e) // If valid
|
||||
{
|
||||
uint8_t *x = p+1;
|
||||
unsigned long len = 0;
|
||||
e = p + 1 + p[0];
|
||||
while (x+len<e && x[len] != '=') len++;
|
||||
if (len >= keyBufLen) return(kDNSServiceErr_NoMemory);
|
||||
memcpy(key, x, len);
|
||||
key[len] = 0;
|
||||
if (x+len<e) // If we found '='
|
||||
{
|
||||
*value = x + len + 1;
|
||||
*valueLen = (uint8_t)(p[0] - (len + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
*value = NULL;
|
||||
*valueLen = 0;
|
||||
}
|
||||
return(kDNSServiceErr_NoError);
|
||||
}
|
||||
return(kDNSServiceErr_Invalid);
|
||||
}
|
||||
(
|
||||
uint16_t txtLen,
|
||||
const void *txtRecord,
|
||||
uint16_t itemIndex,
|
||||
uint16_t keyBufLen,
|
||||
char *key,
|
||||
uint8_t *valueLen,
|
||||
const void **value
|
||||
)
|
||||
{
|
||||
uint16_t count = 0;
|
||||
uint8_t *p = (uint8_t*)txtRecord;
|
||||
uint8_t *e = p + txtLen;
|
||||
while (p<e && count<itemIndex) { p += 1 + p[0]; count++; } // Find requested item
|
||||
if (p<e && p + 1 + p[0] <= e) // If valid
|
||||
{
|
||||
uint8_t *x = p+1;
|
||||
unsigned long len = 0;
|
||||
e = p + 1 + p[0];
|
||||
while (x+len<e && x[len] != '=') len++;
|
||||
if (len >= keyBufLen) return(kDNSServiceErr_NoMemory);
|
||||
memcpy(key, x, len);
|
||||
key[len] = 0;
|
||||
if (x+len<e) // If we found '='
|
||||
{
|
||||
*value = x + len + 1;
|
||||
*valueLen = (uint8_t)(p[0] - (len + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
*value = NULL;
|
||||
*valueLen = 0;
|
||||
}
|
||||
return(kDNSServiceErr_NoError);
|
||||
}
|
||||
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
|
||||
|
||||
// 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"
|
||||
// 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)
|
||||
|
||||
// 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
|
||||
// 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 -*-
|
||||
*
|
||||
* 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
|
||||
* 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,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* 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
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
@ -31,131 +31,131 @@
|
||||
#if defined(_WIN32)
|
||||
|
||||
char *win32_strerror(int inErrorCode)
|
||||
{
|
||||
static char buffer[1024];
|
||||
DWORD n;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
n = FormatMessageA(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
(DWORD) inErrorCode,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
NULL);
|
||||
if (n > 0)
|
||||
{
|
||||
// Remove any trailing CR's or LF's since some messages have them.
|
||||
while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
|
||||
buffer[--n] = '\0';
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
{
|
||||
static char buffer[1024];
|
||||
DWORD n;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
n = FormatMessageA(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
(DWORD) inErrorCode,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
NULL);
|
||||
if (n > 0)
|
||||
{
|
||||
// Remove any trailing CR's or LF's since some messages have them.
|
||||
while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
|
||||
buffer[--n] = '\0';
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void put_uint32(const uint32_t l, char **ptr)
|
||||
{
|
||||
(*ptr)[0] = (char)((l >> 24) & 0xFF);
|
||||
(*ptr)[1] = (char)((l >> 16) & 0xFF);
|
||||
(*ptr)[2] = (char)((l >> 8) & 0xFF);
|
||||
(*ptr)[3] = (char)((l ) & 0xFF);
|
||||
*ptr += sizeof(uint32_t);
|
||||
}
|
||||
{
|
||||
(*ptr)[0] = (char)((l >> 24) & 0xFF);
|
||||
(*ptr)[1] = (char)((l >> 16) & 0xFF);
|
||||
(*ptr)[2] = (char)((l >> 8) & 0xFF);
|
||||
(*ptr)[3] = (char)((l ) & 0xFF);
|
||||
*ptr += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t get_uint32(const char **ptr, const char *end)
|
||||
{
|
||||
if (!*ptr || *ptr + sizeof(uint32_t) > end)
|
||||
{
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *p = (uint8_t*) *ptr;
|
||||
*ptr += sizeof(uint32_t);
|
||||
return((uint32_t) ((uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]));
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!*ptr || *ptr + sizeof(uint32_t) > end)
|
||||
{
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *p = (uint8_t*) *ptr;
|
||||
*ptr += sizeof(uint32_t);
|
||||
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)
|
||||
{
|
||||
(*ptr)[0] = (char)((s >> 8) & 0xFF);
|
||||
(*ptr)[1] = (char)((s ) & 0xFF);
|
||||
*ptr += sizeof(uint16_t);
|
||||
}
|
||||
{
|
||||
(*ptr)[0] = (char)((s >> 8) & 0xFF);
|
||||
(*ptr)[1] = (char)((s ) & 0xFF);
|
||||
*ptr += sizeof(uint16_t);
|
||||
}
|
||||
|
||||
uint16_t get_uint16(const char **ptr, const char *end)
|
||||
{
|
||||
if (!*ptr || *ptr + sizeof(uint16_t) > end)
|
||||
{
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *p = (uint8_t*) *ptr;
|
||||
*ptr += sizeof(uint16_t);
|
||||
return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!*ptr || *ptr + sizeof(uint16_t) > end)
|
||||
{
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *p = (uint8_t*) *ptr;
|
||||
*ptr += sizeof(uint16_t);
|
||||
return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
|
||||
}
|
||||
}
|
||||
|
||||
int put_string(const char *str, char **ptr)
|
||||
{
|
||||
if (!str) str = "";
|
||||
strcpy(*ptr, str);
|
||||
*ptr += strlen(str) + 1;
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
if (!str) str = "";
|
||||
strcpy(*ptr, str);
|
||||
*ptr += strlen(str) + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_string(const char **ptr, const char *const end, char *buffer, int buflen)
|
||||
{
|
||||
if (!*ptr)
|
||||
{
|
||||
*buffer = 0;
|
||||
return(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *lim = buffer + buflen; // Calculate limit
|
||||
while (*ptr < end && buffer < lim)
|
||||
{
|
||||
char c = *buffer++ = *(*ptr)++;
|
||||
if (c == 0) return(0); // Success
|
||||
}
|
||||
if (buffer == lim) buffer--;
|
||||
*buffer = 0; // Failed, so terminate string,
|
||||
*ptr = NULL; // clear pointer,
|
||||
return(-1); // and return failure indication
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!*ptr)
|
||||
{
|
||||
*buffer = 0;
|
||||
return(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *lim = buffer + buflen; // Calculate limit
|
||||
while (*ptr < end && buffer < lim)
|
||||
{
|
||||
char c = *buffer++ = *(*ptr)++;
|
||||
if (c == 0) return(0); // Success
|
||||
}
|
||||
if (buffer == lim) buffer--;
|
||||
*buffer = 0; // Failed, so terminate string,
|
||||
*ptr = NULL; // clear pointer,
|
||||
return(-1); // and return failure indication
|
||||
}
|
||||
}
|
||||
|
||||
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr)
|
||||
{
|
||||
memcpy(*ptr, rdata, rdlen);
|
||||
*ptr += rdlen;
|
||||
}
|
||||
{
|
||||
memcpy(*ptr, rdata, rdlen);
|
||||
*ptr += rdlen;
|
||||
}
|
||||
|
||||
const char *get_rdata(const char **ptr, const char *end, int rdlen)
|
||||
{
|
||||
if (!*ptr || *ptr + rdlen > end)
|
||||
{
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *rd = *ptr;
|
||||
*ptr += rdlen;
|
||||
return rd;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!*ptr || *ptr + rdlen > end)
|
||||
{
|
||||
*ptr = NULL;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *rd = *ptr;
|
||||
*ptr += rdlen;
|
||||
return rd;
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertHeaderBytes(ipc_msg_hdr *hdr)
|
||||
{
|
||||
hdr->version = htonl(hdr->version);
|
||||
hdr->datalen = htonl(hdr->datalen);
|
||||
hdr->ipc_flags = htonl(hdr->ipc_flags);
|
||||
hdr->op = htonl(hdr->op );
|
||||
hdr->reg_index = htonl(hdr->reg_index);
|
||||
}
|
||||
{
|
||||
hdr->version = htonl(hdr->version);
|
||||
hdr->datalen = htonl(hdr->datalen);
|
||||
hdr->ipc_flags = htonl(hdr->ipc_flags);
|
||||
hdr->op = htonl(hdr->op );
|
||||
hdr->reg_index = htonl(hdr->reg_index);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* -*- 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
|
||||
* 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,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* 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
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
@ -35,72 +35,72 @@
|
||||
// Common cross platform services
|
||||
//
|
||||
#if defined(WIN32)
|
||||
# include <winsock2.h>
|
||||
# define dnssd_InvalidSocket INVALID_SOCKET
|
||||
# define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
|
||||
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
|
||||
# define dnssd_EINTR WSAEINTR
|
||||
# define dnssd_ECONNRESET WSAECONNRESET
|
||||
# define dnssd_sock_t SOCKET
|
||||
# define dnssd_socklen_t int
|
||||
# define dnssd_close(sock) closesocket(sock)
|
||||
# define dnssd_errno WSAGetLastError()
|
||||
# define dnssd_strerror(X) win32_strerror(X)
|
||||
# define ssize_t int
|
||||
# define getpid _getpid
|
||||
# define unlink _unlink
|
||||
# include <winsock2.h>
|
||||
# define dnssd_InvalidSocket INVALID_SOCKET
|
||||
# define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
|
||||
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
|
||||
# define dnssd_EINTR WSAEINTR
|
||||
# define dnssd_ECONNRESET WSAECONNRESET
|
||||
# define dnssd_socklen_t int
|
||||
# define dnssd_close(sock) closesocket(sock)
|
||||
# define dnssd_errno WSAGetLastError()
|
||||
# define dnssd_strerror(X) win32_strerror(X)
|
||||
# define ssize_t int
|
||||
# define getpid _getpid
|
||||
# define unlink _unlink
|
||||
extern char *win32_strerror(int inErrorCode);
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/un.h>
|
||||
# include <string.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# define dnssd_InvalidSocket -1
|
||||
# define dnssd_SocketValid(s) ((s) >= 0)
|
||||
# define dnssd_EWOULDBLOCK EWOULDBLOCK
|
||||
# define dnssd_EINTR EINTR
|
||||
# define dnssd_ECONNRESET ECONNRESET
|
||||
# define dnssd_EPIPE EPIPE
|
||||
# define dnssd_sock_t int
|
||||
# define dnssd_socklen_t unsigned int
|
||||
# define dnssd_close(sock) close(sock)
|
||||
# define dnssd_errno errno
|
||||
# define dnssd_strerror(X) strerror(X)
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/un.h>
|
||||
# include <string.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# define dnssd_InvalidSocket -1
|
||||
# define dnssd_SocketValid(s) ((s) >= 0)
|
||||
# define dnssd_EWOULDBLOCK EWOULDBLOCK
|
||||
# define dnssd_EINTR EINTR
|
||||
# define dnssd_ECONNRESET ECONNRESET
|
||||
# define dnssd_EPIPE EPIPE
|
||||
# define dnssd_socklen_t unsigned int
|
||||
# define dnssd_close(sock) close(sock)
|
||||
# define dnssd_errno errno
|
||||
# define dnssd_strerror(X) strerror(X)
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCP_LOOPBACK)
|
||||
# define AF_DNSSD AF_INET
|
||||
# define MDNS_TCP_SERVERADDR "127.0.0.1"
|
||||
# define MDNS_TCP_SERVERPORT 5354
|
||||
# define LISTENQ 5
|
||||
# define dnssd_sockaddr_t struct sockaddr_in
|
||||
# define AF_DNSSD AF_INET
|
||||
# define MDNS_TCP_SERVERADDR "127.0.0.1"
|
||||
# define MDNS_TCP_SERVERPORT 5354
|
||||
# define LISTENQ 5
|
||||
# define dnssd_sockaddr_t struct sockaddr_in
|
||||
#else
|
||||
# define AF_DNSSD AF_LOCAL
|
||||
# ifndef MDNS_UDS_SERVERPATH
|
||||
# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
|
||||
# endif
|
||||
# define LISTENQ 100
|
||||
// longest legal control path length
|
||||
# define MAX_CTLPATH 256
|
||||
# define dnssd_sockaddr_t struct sockaddr_un
|
||||
# define AF_DNSSD AF_LOCAL
|
||||
# ifndef MDNS_UDS_SERVERPATH
|
||||
# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
|
||||
# endif
|
||||
# define MDNS_UDS_SERVERPATH_ENVVAR "DNSSD_UDS_PATH"
|
||||
# define LISTENQ 100
|
||||
// longest legal control path length
|
||||
# define MAX_CTLPATH (sizeof(((struct sockaddr_un*)0)->sun_path))
|
||||
# define dnssd_sockaddr_t struct sockaddr_un
|
||||
#endif
|
||||
|
||||
// Compatibility workaround
|
||||
#ifndef AF_LOCAL
|
||||
#define AF_LOCAL AF_UNIX
|
||||
#define AF_LOCAL AF_UNIX
|
||||
#endif
|
||||
|
||||
// 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
|
||||
#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
|
||||
// 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
|
||||
|
||||
typedef enum
|
||||
{
|
||||
request_op_none = 0, // No request yet received on this connection
|
||||
connection_request = 1, // connected socket via DNSServiceConnect()
|
||||
reg_record_request, // reg/remove record only valid for connected sockets
|
||||
{
|
||||
request_op_none = 0, // No request yet received on this connection
|
||||
connection_request = 1, // connected socket via DNSServiceConnect()
|
||||
reg_record_request, // reg/remove record only valid for connected sockets
|
||||
remove_record_request,
|
||||
enumeration_request,
|
||||
reg_service_request,
|
||||
@ -129,55 +129,58 @@ typedef enum
|
||||
reconfirm_record_request,
|
||||
add_record_request,
|
||||
update_record_request,
|
||||
setdomain_request, // Up to here is in Tiger and B4W 1.0.3
|
||||
getproperty_request, // New in B4W 1.0.4
|
||||
port_mapping_request, // New in Leopard and B4W 2.0
|
||||
addrinfo_request,
|
||||
send_bpf, // New in SL
|
||||
setdomain_request, // Up to here is in Tiger and B4W 1.0.3
|
||||
getproperty_request, // New in B4W 1.0.4
|
||||
port_mapping_request, // New in Leopard and B4W 2.0
|
||||
addrinfo_request,
|
||||
send_bpf, // New in SL
|
||||
getpid_request,
|
||||
release_request,
|
||||
connection_delegate_request,
|
||||
|
||||
cancel_request = 63
|
||||
} request_op_t;
|
||||
cancel_request = 63
|
||||
} request_op_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
{
|
||||
enumeration_reply_op = 64,
|
||||
reg_service_reply_op,
|
||||
browse_reply_op,
|
||||
resolve_reply_op,
|
||||
query_reply_op,
|
||||
reg_record_reply_op, // Up to here is in Tiger and B4W 1.0.3
|
||||
getproperty_reply_op, // New in B4W 1.0.4
|
||||
port_mapping_reply_op, // New in Leopard and B4W 2.0
|
||||
addrinfo_reply_op
|
||||
} reply_op_t;
|
||||
reg_record_reply_op, // Up to here is in Tiger and B4W 1.0.3
|
||||
getproperty_reply_op, // New in B4W 1.0.4
|
||||
port_mapping_reply_op, // New in Leopard and B4W 2.0
|
||||
addrinfo_reply_op
|
||||
} reply_op_t;
|
||||
|
||||
#if defined(_WIN64)
|
||||
# pragma pack(push,4)
|
||||
# pragma pack(push,4)
|
||||
#endif
|
||||
|
||||
// Define context object big enough to hold a 64-bit pointer,
|
||||
// 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
|
||||
typedef packedunion
|
||||
{
|
||||
{
|
||||
void *context;
|
||||
uint32_t u32[2];
|
||||
} client_context_t;
|
||||
} client_context_t;
|
||||
|
||||
typedef packedstruct
|
||||
{
|
||||
{
|
||||
uint32_t version;
|
||||
uint32_t datalen;
|
||||
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
|
||||
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
|
||||
// index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord())
|
||||
} ipc_msg_hdr;
|
||||
} ipc_msg_hdr;
|
||||
|
||||
#if defined(_WIN64)
|
||||
# pragma pack(pop)
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
// 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);
|
||||
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);
|
||||
|
||||
struct CompileTimeAssertionChecks_dnssd_ipc
|
||||
{
|
||||
// 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.
|
||||
char assert0[(sizeof(client_context_t) == 8) ? 1 : -1];
|
||||
char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1];
|
||||
};
|
||||
{
|
||||
// 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.
|
||||
char assert0[(sizeof(client_context_t) == 8) ? 1 : -1];
|
||||
char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1];
|
||||
};
|
||||
|
||||
#endif // DNSSD_IPC_H
|
||||
|
Reference in New Issue
Block a user