xref: /illumos-gate/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h (revision 472cd20d26008f77084ade4c2048159b98c2b705)
1 /* -*- Mode: C; tab-width: 4 -*-
2  *
3  * Copyright (c) 2003-2018 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
14  *     contributors may be used to endorse or promote products derived from this
15  *     software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 /*! @header     DNS Service Discovery
31  *
32  * @discussion  This section describes the functions, callbacks, and data structures
33  *              that make up the DNS Service Discovery API.
34  *
35  *              The DNS Service Discovery API is part of Bonjour, Apple's implementation
36  *              of zero-configuration networking (ZEROCONF).
37  *
38  *              Bonjour allows you to register a network service, such as a
39  *              printer or file server, so that it can be found by name or browsed
40  *              for by service type and domain. Using Bonjour, applications can
41  *              discover what services are available on the network, along with
42  *              all the information -- such as name, IP address, and port --
43  *              necessary to access a particular service.
44  *
45  *              In effect, Bonjour combines the functions of a local DNS server and
46  *              AppleTalk. Bonjour allows applications to provide user-friendly printer
47  *              and server browsing, among other things, over standard IP networks.
48  *              This behavior is a result of combining protocols such as multicast and
49  *              DNS to add new functionality to the network (such as multicast DNS).
50  *
51  *              Bonjour gives applications easy access to services over local IP
52  *              networks without requiring the service or the application to support
53  *              an AppleTalk or a Netbeui stack, and without requiring a DNS server
54  *              for the local network.
55  */
56 
57 /* _DNS_SD_H contains the API version number for this header file
58  * The API version defined in this header file symbol allows for compile-time
59  * checking, so that C code building with earlier versions of the header file
60  * can avoid compile errors trying to use functions that aren't even defined
61  * in those earlier versions. Similar checks may also be performed at run-time:
62  *  => weak linking -- to avoid link failures if run with an earlier
63  *     version of the library that's missing some desired symbol, or
64  *  => DNSServiceGetProperty(DaemonVersion) -- to verify whether the running daemon
65  *     ("system service" on Windows) meets some required minimum functionality level.
66  */
67 
68 #ifndef _DNS_SD_H
69 #define _DNS_SD_H 13108001
70 
71 #ifdef  __cplusplus
72 extern "C" {
73 #endif
74 
75 /* Set to 1 if libdispatch is supported
76  * Note: May also be set by project and/or Makefile
77  */
78 #if defined(__APPLE__)
79 #define _DNS_SD_LIBDISPATCH 1
80 #else
81 #define _DNS_SD_LIBDISPATCH 0
82 #endif
83 
84 /* standard calling convention under Win32 is __stdcall */
85 /* Note: When compiling Intel EFI (Extensible Firmware Interface) under MS Visual Studio, the */
86 /* _WIN32 symbol is defined by the compiler even though it's NOT compiling code for Windows32 */
87 #if defined(_WIN32) && !defined(EFI32) && !defined(EFI64)
88 #define DNSSD_API __stdcall
89 #else
90 #define DNSSD_API
91 #endif
92 
93 #if (defined(__GNUC__) && (__GNUC__ >= 4))
94 #define DNSSD_EXPORT __attribute__((visibility("default")))
95 #else
96 #define DNSSD_EXPORT
97 #endif
98 
99 #if defined(_WIN32)
100 #include <winsock2.h>
101 typedef SOCKET dnssd_sock_t;
102 #else
103 typedef int dnssd_sock_t;
104 #endif
105 
106 /* stdint.h does not exist on FreeBSD 4.x; its types are defined in sys/types.h instead */
107 #if defined(__FreeBSD__) && (__FreeBSD__ < 5)
108 #include <sys/types.h>
109 
110 /* Likewise, on Sun, standard integer types are in sys/types.h */
111 #elif defined(__sun__)
112 #include <sys/types.h>
113 
114 /* EFI does not have stdint.h, or anything else equivalent */
115 #elif defined(EFI32) || defined(EFI64) || defined(EFIX64)
116 #include "Tiano.h"
117 #if !defined(_STDINT_H_)
118 typedef UINT8 uint8_t;
119 typedef INT8 int8_t;
120 typedef UINT16 uint16_t;
121 typedef INT16 int16_t;
122 typedef UINT32 uint32_t;
123 typedef INT32 int32_t;
124 #endif
125 /* Windows has its own differences */
126 #elif defined(_WIN32)
127 #include <windows.h>
128 #define _UNUSED
129 #ifndef _MSL_STDINT_H
130 typedef UINT8 uint8_t;
131 typedef INT8 int8_t;
132 typedef UINT16 uint16_t;
133 typedef INT16 int16_t;
134 typedef UINT32 uint32_t;
135 typedef INT32 int32_t;
136 #endif
137 
138 /* All other Posix platforms use stdint.h */
139 #else
140 #include <stdint.h>
141 #endif
142 
143 #if _DNS_SD_LIBDISPATCH
144 #include <dispatch/dispatch.h>
145 #endif
146 
147 /* DNSServiceRef, DNSRecordRef
148  *
149  * Opaque internal data types.
150  * Note: client is responsible for serializing access to these structures if
151  * they are shared between concurrent threads.
152  */
153 
154 typedef struct _DNSServiceRef_t *DNSServiceRef;
155 typedef struct _DNSRecordRef_t *DNSRecordRef;
156 
157 struct sockaddr;
158 
159 /*! @enum General flags
160  * Most DNS-SD API functions and callbacks include a DNSServiceFlags parameter.
161  * As a general rule, any given bit in the 32-bit flags field has a specific fixed meaning,
162  * regardless of the function or callback being used. For any given function or callback,
163  * typically only a subset of the possible flags are meaningful, and all others should be zero.
164  * The discussion section for each API call describes which flags are valid for that call
165  * and callback. In some cases, for a particular call, it may be that no flags are currently
166  * defined, in which case the DNSServiceFlags parameter exists purely to allow future expansion.
167  * In all cases, developers should expect that in future releases, it is possible that new flag
168  * values will be defined, and write code with this in mind. For example, code that tests
169  *     if (flags == kDNSServiceFlagsAdd) ...
170  * will fail if, in a future release, another bit in the 32-bit flags field is also set.
171  * The reliable way to test whether a particular bit is set is not with an equality test,
172  * but with a bitwise mask:
173  *     if (flags & kDNSServiceFlagsAdd) ...
174  * With the exception of kDNSServiceFlagsValidate, each flag can be valid(be set)
175  * EITHER only as an input to one of the DNSService*() APIs OR only as an output
176  * (provide status) through any of the callbacks used. For example, kDNSServiceFlagsAdd
177  * can be set only as an output in the callback, whereas the kDNSServiceFlagsIncludeP2P
178  * can be set only as an input to the DNSService*() APIs. See comments on kDNSServiceFlagsValidate
179  * defined in enum below.
180  */
181 enum
182 {
183     kDNSServiceFlagsMoreComing          = 0x1,
184     /* MoreComing indicates to a callback that at least one more result is
185      * queued and will be delivered following immediately after this one.
186      * When the MoreComing flag is set, applications should not immediately
187      * update their UI, because this can result in a great deal of ugly flickering
188      * on the screen, and can waste a great deal of CPU time repeatedly updating
189      * the screen with content that is then immediately erased, over and over.
190      * Applications should wait until MoreComing is not set, and then
191      * update their UI when no more changes are imminent.
192      * When MoreComing is not set, that doesn't mean there will be no more
193      * answers EVER, just that there are no more answers immediately
194      * available right now at this instant. If more answers become available
195      * in the future they will be delivered as usual.
196      */
197 
198     kDNSServiceFlagsAutoTrigger        = 0x1,
199     /* Valid for browses using kDNSServiceInterfaceIndexAny.
200      * Will auto trigger the browse over AWDL as well once the service is discovered
201      * over BLE.
202      * This flag is an input value to DNSServiceBrowse(), which is why we can
203      * use the same value as kDNSServiceFlagsMoreComing, which is an output flag
204      * for various client callbacks.
205     */
206 
207     kDNSServiceFlagsAdd                 = 0x2,
208     kDNSServiceFlagsDefault             = 0x4,
209     /* Flags for domain enumeration and browse/query reply callbacks.
210      * "Default" applies only to enumeration and is only valid in
211      * conjunction with "Add". An enumeration callback with the "Add"
212      * flag NOT set indicates a "Remove", i.e. the domain is no longer
213      * valid.
214      */
215 
216     kDNSServiceFlagsNoAutoRename        = 0x8,
217     /* Flag for specifying renaming behavior on name conflict when registering
218      * non-shared records. By default, name conflicts are automatically handled
219      * by renaming the service. NoAutoRename overrides this behavior - with this
220      * flag set, name conflicts will result in a callback. The NoAutorename flag
221      * is only valid if a name is explicitly specified when registering a service
222      * (i.e. the default name is not used.)
223      */
224 
225     kDNSServiceFlagsShared              = 0x10,
226     kDNSServiceFlagsUnique              = 0x20,
227     /* Flag for registering individual records on a connected
228      * DNSServiceRef. Shared indicates that there may be multiple records
229      * with this name on the network (e.g. PTR records). Unique indicates that the
230      * record's name is to be unique on the network (e.g. SRV records).
231      */
232 
233     kDNSServiceFlagsBrowseDomains       = 0x40,
234     kDNSServiceFlagsRegistrationDomains = 0x80,
235     /* Flags for specifying domain enumeration type in DNSServiceEnumerateDomains.
236      * BrowseDomains enumerates domains recommended for browsing, RegistrationDomains
237      * enumerates domains recommended for registration.
238      */
239 
240     kDNSServiceFlagsLongLivedQuery      = 0x100,
241     /* Flag for creating a long-lived unicast query for the DNSServiceQueryRecord call. */
242 
243     kDNSServiceFlagsAllowRemoteQuery    = 0x200,
244     /* Flag for creating a record for which we will answer remote queries
245      * (queries from hosts more than one hop away; hosts not directly connected to the local link).
246      */
247 
248     kDNSServiceFlagsForceMulticast      = 0x400,
249     /* Flag for signifying that a query or registration should be performed exclusively via multicast
250      * DNS, even for a name in a domain (e.g. foo.apple.com.) that would normally imply unicast DNS.
251      */
252 
253     kDNSServiceFlagsForce               = 0x800,    // This flag is deprecated.
254 
255     kDNSServiceFlagsKnownUnique         = 0x800,
256     /*
257      * Client guarantees that record names are unique, so we can skip sending out initial
258      * probe messages.  Standard name conflict resolution is still done if a conflict is discovered.
259      */
260 
261     kDNSServiceFlagsReturnIntermediates = 0x1000,
262     /* Flag for returning intermediate results.
263      * For example, if a query results in an authoritative NXDomain (name does not exist)
264      * then that result is returned to the client. However the query is not implicitly
265      * cancelled -- it remains active and if the answer subsequently changes
266      * (e.g. because a VPN tunnel is subsequently established) then that positive
267      * result will still be returned to the client.
268      * Similarly, if a query results in a CNAME record, then in addition to following
269      * the CNAME referral, the intermediate CNAME result is also returned to the client.
270      * When this flag is not set, NXDomain errors are not returned, and CNAME records
271      * are followed silently without informing the client of the intermediate steps.
272      * (In earlier builds this flag was briefly calledkDNSServiceFlagsReturnCNAME)
273      */
274 
275     kDNSServiceFlagsShareConnection     = 0x4000,
276     /* For efficiency, clients that perform many concurrent operations may want to use a
277      * single Unix Domain Socket connection with the background daemon, instead of having a
278      * separate connection for each independent operation. To use this mode, clients first
279      * call DNSServiceCreateConnection(&SharedRef) to initialize the main DNSServiceRef.
280      * For each subsequent operation that is to share that same connection, the client copies
281      * the SharedRef, and then passes the address of that copy, setting the ShareConnection flag
282      * to tell the library that this DNSServiceRef is not a typical uninitialized DNSServiceRef;
283      * it's a copy of an existing DNSServiceRef whose connection information should be reused.
284      *
285      * For example:
286      *
287      * DNSServiceErrorType error;
288      * DNSServiceRef SharedRef;
289      * error = DNSServiceCreateConnection(&SharedRef);
290      * if (error) ...
291      * DNSServiceRef BrowseRef = SharedRef;  // Important: COPY the primary DNSServiceRef first...
292      * error = DNSServiceBrowse(&BrowseRef, kDNSServiceFlagsShareConnection, ...); // then use the copy
293      * if (error) ...
294      * ...
295      * DNSServiceRefDeallocate(BrowseRef); // Terminate the browse operation
296      * DNSServiceRefDeallocate(SharedRef); // Terminate the shared connection
297      *
298      * Notes:
299      *
300      * 1. Collective kDNSServiceFlagsMoreComing flag
301      * When callbacks are invoked using a shared DNSServiceRef, the
302      * kDNSServiceFlagsMoreComing flag applies collectively to *all* active
303      * operations sharing the same parent DNSServiceRef. If the MoreComing flag is
304      * set it means that there are more results queued on this parent DNSServiceRef,
305      * but not necessarily more results for this particular callback function.
306      * The implication of this for client programmers is that when a callback
307      * is invoked with the MoreComing flag set, the code should update its
308      * internal data structures with the new result, and set a variable indicating
309      * that its UI needs to be updated. Then, later when a callback is eventually
310      * invoked with the MoreComing flag not set, the code should update *all*
311      * stale UI elements related to that shared parent DNSServiceRef that need
312      * updating, not just the UI elements related to the particular callback
313      * that happened to be the last one to be invoked.
314      *
315      * 2. Canceling operations and kDNSServiceFlagsMoreComing
316      * Whenever you cancel any operation for which you had deferred UI updates
317      * waiting because of a kDNSServiceFlagsMoreComing flag, you should perform
318      * those deferred UI updates. This is because, after cancelling the operation,
319      * you can no longer wait for a callback *without* MoreComing set, to tell
320      * you do perform your deferred UI updates (the operation has been canceled,
321      * so there will be no more callbacks). An implication of the collective
322      * kDNSServiceFlagsMoreComing flag for shared connections is that this
323      * guideline applies more broadly -- any time you cancel an operation on
324      * a shared connection, you should perform all deferred UI updates for all
325      * operations sharing that connection. This is because the MoreComing flag
326      * might have been referring to events coming for the operation you canceled,
327      * which will now not be coming because the operation has been canceled.
328      *
329      * 3. Only share DNSServiceRef's created with DNSServiceCreateConnection
330      * Calling DNSServiceCreateConnection(&ref) creates a special shareable DNSServiceRef.
331      * DNSServiceRef's created by other calls like DNSServiceBrowse() or DNSServiceResolve()
332      * cannot be shared by copying them and using kDNSServiceFlagsShareConnection.
333      *
334      * 4. Don't Double-Deallocate
335      * Calling DNSServiceRefDeallocate(OpRef) for a particular operation's DNSServiceRef terminates
336      * just that operation. Calling DNSServiceRefDeallocate(SharedRef) for the main shared DNSServiceRef
337      * (the parent DNSServiceRef, originally created by DNSServiceCreateConnection(&SharedRef))
338      * automatically terminates the shared connection *and* all operations that were still using it.
339      * After doing this, DO NOT then attempt to deallocate any remaining subordinate DNSServiceRef's.
340      * The memory used by those subordinate DNSServiceRef's has already been freed, so any attempt
341      * to do a DNSServiceRefDeallocate (or any other operation) on them will result in accesses
342      * to freed memory, leading to crashes or other equally undesirable results.
343      * You can deallocate individual operations first and then deallocate the parent DNSServiceRef last,
344      * but if you deallocate the parent DNSServiceRef first, then all of the subordinate DNSServiceRef's
345      * are implicitly deallocated, and explicitly deallocating them a second time will lead to crashes.
346      *
347      * 5. Thread Safety
348      * The dns_sd.h API does not presuppose any particular threading model, and consequently
349      * does no locking internally (which would require linking with a specific threading library).
350      * If the client concurrently, from multiple threads (or contexts), calls API routines using
351      * the same DNSServiceRef, it is the client's responsibility to provide mutual exclusion for
352      * that DNSServiceRef.
353      *
354      * For example, use of DNSServiceRefDeallocate requires caution. A common mistake is as follows:
355      * Thread B calls DNSServiceRefDeallocate to deallocate sdRef while Thread A is processing events
356      * using sdRef. Doing this will lead to intermittent crashes on thread A if the sdRef is used after
357      * it was deallocated.
358      *
359      * A telltale sign of this crash type is to see DNSServiceProcessResult on the stack preceding the
360      * actual crash location.
361      *
362      * To state this more explicitly, mDNSResponder does not queue DNSServiceRefDeallocate so
363      * that it occurs discretely before or after an event is handled.
364      */
365 
366     kDNSServiceFlagsSuppressUnusable    = 0x8000,
367     /*
368      * This flag is meaningful only in DNSServiceQueryRecord which suppresses unusable queries on the
369      * wire. If "hostname" is a wide-area unicast DNS hostname (i.e. not a ".local." name)
370      * but this host has no routable IPv6 address, then the call will not try to look up IPv6 addresses
371      * for "hostname", since any addresses it found would be unlikely to be of any use anyway. Similarly,
372      * if this host has no routable IPv4 address, the call will not try to look up IPv4 addresses for
373      * "hostname".
374      */
375 
376     kDNSServiceFlagsTimeout            = 0x10000,
377     /*
378      * When kDNServiceFlagsTimeout is passed to DNSServiceQueryRecord or DNSServiceGetAddrInfo, the query is
379      * stopped after a certain number of seconds have elapsed. The time at which the query will be stopped
380      * is determined by the system and cannot be configured by the user. The query will be stopped irrespective
381      * of whether a response was given earlier or not. When the query is stopped, the callback will be called
382      * with an error code of kDNSServiceErr_Timeout and a NULL sockaddr will be returned for DNSServiceGetAddrInfo
383      * and zero length rdata will be returned for DNSServiceQueryRecord.
384      */
385 
386     kDNSServiceFlagsIncludeP2P          = 0x20000,
387     /*
388      * Include P2P interfaces when kDNSServiceInterfaceIndexAny is specified.
389      * By default, specifying kDNSServiceInterfaceIndexAny does not include P2P interfaces.
390      */
391 
392     kDNSServiceFlagsWakeOnResolve      = 0x40000,
393     /*
394     * This flag is meaningful only in DNSServiceResolve. When set, it tries to send a magic packet
395     * to wake up the client.
396     */
397 
398     kDNSServiceFlagsBackgroundTrafficClass  = 0x80000,
399     /*
400     * This flag is meaningful for Unicast DNS queries. When set, it uses the background traffic
401     * class for packets that service the request.
402     */
403 
404     kDNSServiceFlagsIncludeAWDL      = 0x100000,
405    /*
406     * Include AWDL interface when kDNSServiceInterfaceIndexAny is specified.
407     */
408 
409     kDNSServiceFlagsEnableDNSSEC           = 0x200000,
410     /*
411      * Perform DNSSEC validation on the client request when kDNSServiceFlagsEnableDNSSEC is specified
412      * Since the client API has not been finalized, we will use it as a temporary flag to turn on the DNSSEC validation.
413      */
414 
415     kDNSServiceFlagsValidate               = 0x200000,
416    /*
417     * This flag is meaningful in DNSServiceGetAddrInfo and DNSServiceQueryRecord. This is the ONLY flag to be valid
418     * as an input to the APIs and also an output through the callbacks in the APIs.
419     *
420     * When this flag is passed to DNSServiceQueryRecord and DNSServiceGetAddrInfo to resolve unicast names,
421     * the response  will be validated using DNSSEC. The validation results are delivered using the flags field in
422     * the callback and kDNSServiceFlagsValidate is marked in the flags to indicate that DNSSEC status is also available.
423     * When the callback is called to deliver the query results, the validation results may or may not be available.
424     * If it is not delivered along with the results, the validation status is delivered when the validation completes.
425     *
426     * When the validation results are delivered in the callback, it is indicated by marking the flags with
427     * kDNSServiceFlagsValidate and kDNSServiceFlagsAdd along with the DNSSEC status flags (described below) and a NULL
428     * sockaddr will be returned for DNSServiceGetAddrInfo and zero length rdata will be returned for DNSServiceQueryRecord.
429     * DNSSEC validation results are for the whole RRSet and not just individual records delivered in the callback. When
430     * kDNSServiceFlagsAdd is not set in the flags, applications should implicitly assume that the DNSSEC status of the
431     * RRSet that has been delivered up until that point is not valid anymore, till another callback is called with
432     * kDNSServiceFlagsAdd and kDNSServiceFlagsValidate.
433     *
434     * The following four flags indicate the status of the DNSSEC validation and marked in the flags field of the callback.
435     * When any of the four flags is set, kDNSServiceFlagsValidate will also be set. To check the validation status, the
436     * other applicable output flags should be masked.
437     */
438 
439     kDNSServiceFlagsSecure                 = 0x200010,
440    /*
441     * The response has been validated by verifying all the signatures in the response and was able to
442     * build a successful authentication chain starting from a known trust anchor.
443     */
444 
445     kDNSServiceFlagsInsecure               = 0x200020,
446    /*
447     * A chain of trust cannot be built starting from a known trust anchor to the response.
448     */
449 
450     kDNSServiceFlagsBogus                  = 0x200040,
451    /*
452     * If the response cannot be verified to be secure due to expired signatures, missing signatures etc.,
453     * then the results are considered to be bogus.
454     */
455 
456     kDNSServiceFlagsIndeterminate          = 0x200080,
457    /*
458     * There is no valid trust anchor that can be used to determine whether a response is secure or not.
459     */
460 
461     kDNSServiceFlagsUnicastResponse        = 0x400000,
462    /*
463     * Request unicast response to query.
464     */
465     kDNSServiceFlagsValidateOptional       = 0x800000,
466 
467     /*
468      * This flag is identical to kDNSServiceFlagsValidate except for the case where the response
469      * cannot be validated. If this flag is set in DNSServiceQueryRecord or DNSServiceGetAddrInfo,
470      * the DNSSEC records will be requested for validation. If they cannot be received for some reason
471      * during the validation (e.g., zone is not signed, zone is signed but cannot be traced back to
472      * root, recursive server does not understand DNSSEC etc.), then this will fallback to the default
473      * behavior where the validation will not be performed and no DNSSEC results will be provided.
474      *
475      * If the zone is signed and there is a valid path to a known trust anchor configured in the system
476      * and the application requires DNSSEC validation irrespective of the DNSSEC awareness in the current
477      * network, then this option MUST not be used. This is only intended to be used during the transition
478      * period where the different nodes participating in the DNS resolution may not understand DNSSEC or
479      * managed properly (e.g. missing DS record) but still want to be able to resolve DNS successfully.
480      */
481 
482     kDNSServiceFlagsWakeOnlyService        = 0x1000000,
483     /*
484      * This flag is meaningful only in DNSServiceRegister. When set, the service will not be registered
485      * with sleep proxy server during sleep.
486      */
487 
488     kDNSServiceFlagsThresholdOne           = 0x2000000,
489     kDNSServiceFlagsThresholdFinder        = 0x4000000,
490     kDNSServiceFlagsThresholdReached       = kDNSServiceFlagsThresholdOne,
491     /*
492      * kDNSServiceFlagsThresholdOne is meaningful only in DNSServiceBrowse. When set,
493      * the system will stop issuing browse queries on the network once the number
494      * of answers returned is one or more.  It will issue queries on the network
495      * again if the number of answers drops to zero.
496      * This flag is for Apple internal use only. Third party developers
497      * should not rely on this behavior being supported in any given software release.
498      *
499      * kDNSServiceFlagsThresholdFinder is meaningful only in DNSServiceBrowse. When set,
500      * the system will stop issuing browse queries on the network once the number
501      * of answers has reached the threshold set for Finder.
502      * It will issue queries on the network again if the number of answers drops below
503      * this threshold.
504      * This flag is for Apple internal use only. Third party developers
505      * should not rely on this behavior being supported in any given software release.
506      *
507      * When kDNSServiceFlagsThresholdReached is set in the client callback add or remove event,
508      * it indicates that the browse answer threshold has been reached and no
509      * browse requests will be generated on the network until the number of answers falls
510      * below the threshold value.  Add and remove events can still occur based
511      * on incoming Bonjour traffic observed by the system.
512      * The set of services return to the client is not guaranteed to represent the
513      * entire set of services present on the network once the threshold has been reached.
514      *
515      * Note, while kDNSServiceFlagsThresholdReached and kDNSServiceFlagsThresholdOne
516      * have the same value, there  isn't a conflict because kDNSServiceFlagsThresholdReached
517      * is only set in the callbacks and kDNSServiceFlagsThresholdOne is only set on
518      * input to a DNSServiceBrowse call.
519      */
520      kDNSServiceFlagsPrivateOne          = 0x2000,
521     /*
522      * This flag is private and should not be used.
523      */
524 
525      kDNSServiceFlagsPrivateTwo           = 0x8000000,
526     /*
527      * This flag is private and should not be used.
528      */
529 
530      kDNSServiceFlagsPrivateThree         = 0x10000000,
531     /*
532      * This flag is private and should not be used.
533      */
534 
535      kDNSServiceFlagsPrivateFour          = 0x20000000,
536     /*
537      * This flag is private and should not be used.
538      */
539 
540     kDNSServiceFlagsPrivateFive          = 0x40000000,
541     /*
542      * This flag is private and should not be used.
543      */
544 
545 
546     kDNSServiceFlagAnsweredFromCache     = 0x40000000,
547     /*
548      * When kDNSServiceFlagAnsweredFromCache is passed back in the flags parameter of DNSServiceQueryRecordReply or DNSServiceGetAddrInfoReply,
549      * an answer will have this flag set if it was answered from the cache.
550      */
551 
552     kDNSServiceFlagsAllowExpiredAnswers   = 0x80000000,
553     /*
554      * When kDNSServiceFlagsAllowExpiredAnswers is passed to DNSServiceQueryRecord or DNSServiceGetAddrInfo,
555      * if there are matching expired records still in the cache, then they are immediately returned to the
556      * client, and in parallel a network query for that name is issued. All returned records from the query will
557      * remain in the cache after expiration.
558      */
559 
560     kDNSServiceFlagsExpiredAnswer         = 0x80000000
561     /*
562      * When kDNSServiceFlagsAllowExpiredAnswers is passed to DNSServiceQueryRecord or DNSServiceGetAddrInfo,
563      * an expired answer will have this flag set.
564      */
565 
566 };
567 
568 /* Possible protocol values */
569 enum
570 {
571     /* for DNSServiceGetAddrInfo() */
572     kDNSServiceProtocol_IPv4 = 0x01,
573     kDNSServiceProtocol_IPv6 = 0x02,
574     /* 0x04 and 0x08 reserved for future internetwork protocols */
575 
576     /* for DNSServiceNATPortMappingCreate() */
577     kDNSServiceProtocol_UDP  = 0x10,
578     kDNSServiceProtocol_TCP  = 0x20
579                                /* 0x40 and 0x80 reserved for future transport protocols, e.g. SCTP [RFC 2960]
580                                 * or DCCP [RFC 4340]. If future NAT gateways are created that support port
581                                 * mappings for these protocols, new constants will be defined here.
582                                 */
583 };
584 
585 /*
586  * The values for DNS Classes and Types are listed in RFC 1035, and are available
587  * on every OS in its DNS header file. Unfortunately every OS does not have the
588  * same header file containing DNS Class and Type constants, and the names of
589  * the constants are not consistent. For example, BIND 8 uses "T_A",
590  * BIND 9 uses "ns_t_a", Windows uses "DNS_TYPE_A", etc.
591  * For this reason, these constants are also listed here, so that code using
592  * the DNS-SD programming APIs can use these constants, so that the same code
593  * can compile on all our supported platforms.
594  */
595 
596 enum
597 {
598     kDNSServiceClass_IN       = 1       /* Internet */
599 };
600 
601 enum
602 {
603     kDNSServiceType_A          = 1,      /* Host address. */
604     kDNSServiceType_NS         = 2,      /* Authoritative server. */
605     kDNSServiceType_MD         = 3,      /* Mail destination. */
606     kDNSServiceType_MF         = 4,      /* Mail forwarder. */
607     kDNSServiceType_CNAME      = 5,      /* Canonical name. */
608     kDNSServiceType_SOA        = 6,      /* Start of authority zone. */
609     kDNSServiceType_MB         = 7,      /* Mailbox domain name. */
610     kDNSServiceType_MG         = 8,      /* Mail group member. */
611     kDNSServiceType_MR         = 9,      /* Mail rename name. */
612     kDNSServiceType_NULL       = 10,     /* Null resource record. */
613     kDNSServiceType_WKS        = 11,     /* Well known service. */
614     kDNSServiceType_PTR        = 12,     /* Domain name pointer. */
615     kDNSServiceType_HINFO      = 13,     /* Host information. */
616     kDNSServiceType_MINFO      = 14,     /* Mailbox information. */
617     kDNSServiceType_MX         = 15,     /* Mail routing information. */
618     kDNSServiceType_TXT        = 16,     /* One or more text strings (NOT "zero or more..."). */
619     kDNSServiceType_RP         = 17,     /* Responsible person. */
620     kDNSServiceType_AFSDB      = 18,     /* AFS cell database. */
621     kDNSServiceType_X25        = 19,     /* X_25 calling address. */
622     kDNSServiceType_ISDN       = 20,     /* ISDN calling address. */
623     kDNSServiceType_RT         = 21,     /* Router. */
624     kDNSServiceType_NSAP       = 22,     /* NSAP address. */
625     kDNSServiceType_NSAP_PTR   = 23,     /* Reverse NSAP lookup (deprecated). */
626     kDNSServiceType_SIG        = 24,     /* Security signature. */
627     kDNSServiceType_KEY        = 25,     /* Security key. */
628     kDNSServiceType_PX         = 26,     /* X.400 mail mapping. */
629     kDNSServiceType_GPOS       = 27,     /* Geographical position (withdrawn). */
630     kDNSServiceType_AAAA       = 28,     /* IPv6 Address. */
631     kDNSServiceType_LOC        = 29,     /* Location Information. */
632     kDNSServiceType_NXT        = 30,     /* Next domain (security). */
633     kDNSServiceType_EID        = 31,     /* Endpoint identifier. */
634     kDNSServiceType_NIMLOC     = 32,     /* Nimrod Locator. */
635     kDNSServiceType_SRV        = 33,     /* Server Selection. */
636     kDNSServiceType_ATMA       = 34,     /* ATM Address */
637     kDNSServiceType_NAPTR      = 35,     /* Naming Authority PoinTeR */
638     kDNSServiceType_KX         = 36,     /* Key Exchange */
639     kDNSServiceType_CERT       = 37,     /* Certification record */
640     kDNSServiceType_A6         = 38,     /* IPv6 Address (deprecated) */
641     kDNSServiceType_DNAME      = 39,     /* Non-terminal DNAME (for IPv6) */
642     kDNSServiceType_SINK       = 40,     /* Kitchen sink (experimental) */
643     kDNSServiceType_OPT        = 41,     /* EDNS0 option (meta-RR) */
644     kDNSServiceType_APL        = 42,     /* Address Prefix List */
645     kDNSServiceType_DS         = 43,     /* Delegation Signer */
646     kDNSServiceType_SSHFP      = 44,     /* SSH Key Fingerprint */
647     kDNSServiceType_IPSECKEY   = 45,     /* IPSECKEY */
648     kDNSServiceType_RRSIG      = 46,     /* RRSIG */
649     kDNSServiceType_NSEC       = 47,     /* Denial of Existence */
650     kDNSServiceType_DNSKEY     = 48,     /* DNSKEY */
651     kDNSServiceType_DHCID      = 49,     /* DHCP Client Identifier */
652     kDNSServiceType_NSEC3      = 50,     /* Hashed Authenticated Denial of Existence */
653     kDNSServiceType_NSEC3PARAM = 51,     /* Hashed Authenticated Denial of Existence */
654 
655     kDNSServiceType_HIP        = 55,     /* Host Identity Protocol */
656 
657     kDNSServiceType_SVCB       = 64,     /* Service Binding. */
658     kDNSServiceType_HTTPS      = 65,      /* HTTPS Service Binding. */
659 
660     kDNSServiceType_SPF        = 99,     /* Sender Policy Framework for E-Mail */
661     kDNSServiceType_UINFO      = 100,    /* IANA-Reserved */
662     kDNSServiceType_UID        = 101,    /* IANA-Reserved */
663     kDNSServiceType_GID        = 102,    /* IANA-Reserved */
664     kDNSServiceType_UNSPEC     = 103,    /* IANA-Reserved */
665 
666     kDNSServiceType_TKEY       = 249,    /* Transaction key */
667     kDNSServiceType_TSIG       = 250,    /* Transaction signature. */
668     kDNSServiceType_IXFR       = 251,    /* Incremental zone transfer. */
669     kDNSServiceType_AXFR       = 252,    /* Transfer zone of authority. */
670     kDNSServiceType_MAILB      = 253,    /* Transfer mailbox records. */
671     kDNSServiceType_MAILA      = 254,    /* Transfer mail agent records. */
672     kDNSServiceType_ANY        = 255    /* Wildcard match. */
673 };
674 
675 /* possible error code values */
676 enum
677 {
678     kDNSServiceErr_NoError                   = 0,
679     kDNSServiceErr_Unknown                   = -65537,  /* 0xFFFE FFFF */
680     kDNSServiceErr_NoSuchName                = -65538,
681     kDNSServiceErr_NoMemory                  = -65539,
682     kDNSServiceErr_BadParam                  = -65540,
683     kDNSServiceErr_BadReference              = -65541,
684     kDNSServiceErr_BadState                  = -65542,
685     kDNSServiceErr_BadFlags                  = -65543,
686     kDNSServiceErr_Unsupported               = -65544,
687     kDNSServiceErr_NotInitialized            = -65545,
688     kDNSServiceErr_AlreadyRegistered         = -65547,
689     kDNSServiceErr_NameConflict              = -65548,
690     kDNSServiceErr_Invalid                   = -65549,
691     kDNSServiceErr_Firewall                  = -65550,
692     kDNSServiceErr_Incompatible              = -65551,  /* client library incompatible with daemon */
693     kDNSServiceErr_BadInterfaceIndex         = -65552,
694     kDNSServiceErr_Refused                   = -65553,
695     kDNSServiceErr_NoSuchRecord              = -65554,
696     kDNSServiceErr_NoAuth                    = -65555,
697     kDNSServiceErr_NoSuchKey                 = -65556,
698     kDNSServiceErr_NATTraversal              = -65557,
699     kDNSServiceErr_DoubleNAT                 = -65558,
700     kDNSServiceErr_BadTime                   = -65559,  /* Codes up to here existed in Tiger */
701     kDNSServiceErr_BadSig                    = -65560,
702     kDNSServiceErr_BadKey                    = -65561,
703     kDNSServiceErr_Transient                 = -65562,
704     kDNSServiceErr_ServiceNotRunning         = -65563,  /* Background daemon not running */
705     kDNSServiceErr_NATPortMappingUnsupported = -65564,  /* NAT doesn't support PCP, NAT-PMP or UPnP */
706     kDNSServiceErr_NATPortMappingDisabled    = -65565,  /* NAT supports PCP, NAT-PMP or UPnP, but it's disabled by the administrator */
707     kDNSServiceErr_NoRouter                  = -65566,  /* No router currently configured (probably no network connectivity) */
708     kDNSServiceErr_PollingMode               = -65567,
709     kDNSServiceErr_Timeout                   = -65568,
710     kDNSServiceErr_DefunctConnection         = -65569,  /* Connection to daemon returned a SO_ISDEFUNCT error result */
711     kDNSServiceErr_PolicyDenied              = -65570
712 
713                                                /* mDNS Error codes are in the range
714                                                 * FFFE FF00 (-65792) to FFFE FFFF (-65537) */
715 };
716 
717 /* Maximum length, in bytes, of a service name represented as a */
718 /* literal C-String, including the terminating NULL at the end. */
719 
720 #define kDNSServiceMaxServiceName 64
721 
722 /* Maximum length, in bytes, of a domain name represented as an *escaped* C-String */
723 /* including the final trailing dot, and the C-String terminating NULL at the end. */
724 
725 #define kDNSServiceMaxDomainName 1009
726 
727 /*
728  * Notes on DNS Name Escaping
729  *   -- or --
730  * "Why is kDNSServiceMaxDomainName 1009, when the maximum legal domain name is 256 bytes?"
731  *
732  * All strings used in the DNS-SD APIs are UTF-8 strings.
733  * Apart from the exceptions noted below, the APIs expect the strings to be properly escaped, using the
734  * conventional DNS escaping rules, as used by the traditional DNS res_query() API, as described below:
735  *
736  * Generally all UTF-8 characters (which includes all US ASCII characters) represent themselves,
737  * with three exceptions:
738  * the dot ('.') character, which is the DNS label separator,
739  * the backslash ('\') character, which is the DNS escape character, and
740  * the ASCII NUL (0) byte value, which is the C-string terminator character.
741  * The escape character ('\') is interpreted as described below:
742  *
743  *   '\ddd', where ddd is a three-digit decimal value from 000 to 255,
744  *        represents a single literal byte with that value. Any byte value may be
745  *        represented in '\ddd' format, even characters that don't strictly need to be escaped.
746  *        For example, the ASCII code for 'w' is 119, and therefore '\119' is equivalent to 'w'.
747  *        Thus the command "ping '\119\119\119.apple.com'" is the equivalent to the command "ping 'www.apple.com'".
748  *        Nonprinting ASCII characters in the range 0-31 are often represented this way.
749  *        In particular, the ASCII NUL character (0) cannot appear in a C-string because C uses it as the
750  *        string terminator character, so ASCII NUL in a domain name has to be represented in a C-string as '\000'.
751  *        Other characters like space (ASCII code 32) are sometimes represented as '\032'
752  *        in contexts where having an actual space character in a C-string would be inconvenient.
753  *
754  *   Otherwise, for all cases where a '\' is followed by anything other than a three-digit decimal value
755  *        from 000 to 255, the character sequence '\x' represents a single literal occurrence of character 'x'.
756  *        This is legal for any character, so, for example, '\w' is equivalent to 'w'.
757  *        Thus the command "ping '\w\w\w.apple.com'" is the equivalent to the command "ping 'www.apple.com'".
758  *        However, this encoding is most useful when representing the characters '.' and '\',
759  *        which otherwise would have special meaning in DNS name strings.
760  *        This means that the following encodings are particularly common:
761  *        '\\' represents a single literal '\' in the name
762  *        '\.' represents a single literal '.' in the name
763  *
764  *   A lone escape character ('\') appearing at the end of a string is not allowed, since it is
765  *        followed by neither a three-digit decimal value from 000 to 255 nor a single character.
766  *        If a lone escape character ('\') does appear as the last character of a string, it is silently ignored.
767  *
768  * The worse-case length for an escaped domain name is calculated as follows:
769  * The longest legal domain name is 256 bytes in wire format (see RFC 6762, Appendix C, DNS Name Length).
770  * For our calculation of the longest *escaped* domain name, we use
771  * the longest legal domain name, with the most characters escaped.
772  *
773  * We consider a domain name of the form: "label63.label63.label63.label62."
774  * where "label63" is a 63-byte label and "label62" is a 62-byte label.
775  * Counting four label-length bytes, 251 bytes of label data, and the terminating zero,
776  * this makes a total of 256 bytes in wire format, the longest legal domain name.
777  *
778  * If each one of the 251 bytes of label data is represented using '\ddd',
779  * then it takes 251 * 4 = 1004 bytes to represent these in a C-string.
780  * Adding four '.' characters as shown above, plus the C-string terminating
781  * zero at the end, results in a maximum storage requirement of 1009 bytes.
782  *
783  * The exceptions, that do not use escaping, are the routines where the full
784  * DNS name of a resource is broken, for convenience, into servicename/regtype/domain.
785  * In these routines, the "servicename" is NOT escaped. It does not need to be, since
786  * it is, by definition, just a single literal string. Any characters in that string
787  * represent exactly what they are. The "regtype" portion is, technically speaking,
788  * escaped, but since legal regtypes are only allowed to contain US ASCII letters,
789  * digits, and hyphens, there is nothing to escape, so the issue is moot.
790  * The "domain" portion is also escaped, though most domains in use on the public
791  * Internet today, like regtypes, don't contain any characters that need to be escaped.
792  * As DNS-SD becomes more popular, rich-text domains for service discovery will
793  * become common, so software should be written to cope with domains with escaping.
794  *
795  * The servicename may be up to 63 bytes of UTF-8 text (not counting the C-String
796  * terminating NULL at the end). The regtype is of the form _service._tcp or
797  * _service._udp, where the "service" part is 1-15 characters, which may be
798  * letters, digits, or hyphens. The domain part of the three-part name may be
799  * any legal domain, providing that the resulting servicename+regtype+domain
800  * name does not exceed 256 bytes.
801  *
802  * For most software, these issues are transparent. When browsing, the discovered
803  * servicenames should simply be displayed as-is. When resolving, the discovered
804  * servicename/regtype/domain are simply passed unchanged to DNSServiceResolve().
805  * When a DNSServiceResolve() succeeds, the returned fullname is already in
806  * the correct format to pass to standard system DNS APIs such as res_query().
807  * For converting from servicename/regtype/domain to a single properly-escaped
808  * full DNS name, the helper function DNSServiceConstructFullName() is provided.
809  *
810  * The following (highly contrived) example illustrates the escaping process.
811  * Suppose you have a service called "Dr. Smith\Dr. Johnson", of type "_ftp._tcp"
812  * in subdomain "4th. Floor" of subdomain "Building 2" of domain "apple.com."
813  * The full (escaped) DNS name of this service's SRV record would be:
814  * Dr\.\032Smith\\Dr\.\032Johnson._ftp._tcp.4th\.\032Floor.Building\0322.apple.com.
815  */
816 
817 
818 /*
819  * Constants for specifying an interface index
820  *
821  * Specific interface indexes are identified via a 32-bit unsigned integer returned
822  * by the if_nametoindex() family of calls.
823  *
824  * If the client passes 0 for interface index, that means "do the right thing",
825  * which (at present) means, "if the name is in an mDNS local multicast domain
826  * (e.g. 'local.', '254.169.in-addr.arpa.', '{8,9,A,B}.E.F.ip6.arpa.') then multicast
827  * on all applicable interfaces, otherwise send via unicast to the appropriate
828  * DNS server." Normally, most clients will use 0 for interface index to
829  * automatically get the default sensible behaviour.
830  *
831  * If the client passes a positive interface index, then that indicates to do the
832  * operation only on that one specified interface.
833  *
834  * If the client passes kDNSServiceInterfaceIndexLocalOnly when registering
835  * a service, then that service will be found *only* by other local clients
836  * on the same machine that are browsing using kDNSServiceInterfaceIndexLocalOnly
837  * or kDNSServiceInterfaceIndexAny.
838  * If a client has a 'private' service, accessible only to other processes
839  * running on the same machine, this allows the client to advertise that service
840  * in a way such that it does not inadvertently appear in service lists on
841  * all the other machines on the network.
842  *
843  * If the client passes kDNSServiceInterfaceIndexLocalOnly when querying or
844  * browsing, then the LocalOnly authoritative records and /etc/hosts caches
845  * are searched and will find *all* records registered or configured on that
846  * same local machine.
847  *
848  * If interested in getting negative answers to local questions while querying
849  * or browsing, then set both the kDNSServiceInterfaceIndexLocalOnly and the
850  * kDNSServiceFlagsReturnIntermediates flags. If no local answers exist at this
851  * moment in time, then the reply will return an immediate negative answer. If
852  * local records are subsequently created that answer the question, then those
853  * answers will be delivered, for as long as the question is still active.
854  *
855  * If the kDNSServiceFlagsTimeout and kDNSServiceInterfaceIndexLocalOnly flags
856  * are set simultaneously when either DNSServiceQueryRecord or DNSServiceGetAddrInfo
857  * is called then both flags take effect. However, if DNSServiceQueryRecord is called
858  * with both the kDNSServiceFlagsSuppressUnusable and kDNSServiceInterfaceIndexLocalOnly
859  * flags set, then the kDNSServiceFlagsSuppressUnusable flag is ignored.
860  *
861  * Clients explicitly wishing to discover *only* LocalOnly services during a
862  * browse may do this, without flags, by inspecting the interfaceIndex of each
863  * service reported to a DNSServiceBrowseReply() callback function, and
864  * discarding those answers where the interface index is not set to
865  * kDNSServiceInterfaceIndexLocalOnly.
866  *
867  * kDNSServiceInterfaceIndexP2P is meaningful only in Browse, QueryRecord, Register,
868  * and Resolve operations. It should not be used in other DNSService APIs.
869  *
870  * - If kDNSServiceInterfaceIndexP2P is passed to DNSServiceBrowse or
871  *   DNSServiceQueryRecord, it restricts the operation to P2P.
872  *
873  * - If kDNSServiceInterfaceIndexP2P is passed to DNSServiceRegister, it is
874  *   mapped internally to kDNSServiceInterfaceIndexAny with the kDNSServiceFlagsIncludeP2P
875  *   set.
876  *
877  * - If kDNSServiceInterfaceIndexP2P is passed to DNSServiceResolve, it is
878  *   mapped internally to kDNSServiceInterfaceIndexAny with the kDNSServiceFlagsIncludeP2P
879  *   set, because resolving a P2P service may create and/or enable an interface whose
880  *   index is not known a priori. The resolve callback will indicate the index of the
881  *   interface via which the service can be accessed.
882  *
883  * If applications pass kDNSServiceInterfaceIndexAny to DNSServiceBrowse
884  * or DNSServiceQueryRecord, they must set the kDNSServiceFlagsIncludeP2P flag
885  * to include P2P. In this case, if a service instance or the record being queried
886  * is found over P2P, the resulting ADD event will indicate kDNSServiceInterfaceIndexP2P
887  * as the interface index.
888  */
889 
890 #define kDNSServiceInterfaceIndexAny 0
891 #define kDNSServiceInterfaceIndexLocalOnly ((uint32_t)-1)
892 #define kDNSServiceInterfaceIndexUnicast   ((uint32_t)-2)
893 #define kDNSServiceInterfaceIndexP2P       ((uint32_t)-3)
894 #define kDNSServiceInterfaceIndexBLE       ((uint32_t)-4)
895 
896 typedef uint32_t DNSServiceFlags;
897 typedef uint32_t DNSServiceProtocol;
898 typedef int32_t DNSServiceErrorType;
899 
900 
901 /*********************************************************************************************
902 *
903 * Version checking
904 *
905 *********************************************************************************************/
906 
907 /* DNSServiceGetProperty() Parameters:
908  *
909  * property:        The requested property.
910  *                  Currently the only property defined is kDNSServiceProperty_DaemonVersion.
911  *
912  * result:          Place to store result.
913  *                  For retrieving DaemonVersion, this should be the address of a uint32_t.
914  *
915  * size:            Pointer to uint32_t containing size of the result location.
916  *                  For retrieving DaemonVersion, this should be sizeof(uint32_t).
917  *                  On return the uint32_t is updated to the size of the data returned.
918  *                  For DaemonVersion, the returned size is always sizeof(uint32_t), but
919  *                  future properties could be defined which return variable-sized results.
920  *
921  * return value:    Returns kDNSServiceErr_NoError on success, or kDNSServiceErr_ServiceNotRunning
922  *                  if the daemon (or "system service" on Windows) is not running.
923  */
924 
925 DNSSD_EXPORT
926 DNSServiceErrorType DNSSD_API DNSServiceGetProperty
927 (
928     const char *property,  /* Requested property (i.e. kDNSServiceProperty_DaemonVersion) */
929     void       *result,    /* Pointer to place to store result */
930     uint32_t   *size       /* size of result location */
931 );
932 
933 /*
934  * When requesting kDNSServiceProperty_DaemonVersion, the result pointer must point
935  * to a 32-bit unsigned integer, and the size parameter must be set to sizeof(uint32_t).
936  *
937  * On return, the 32-bit unsigned integer contains the API version number
938  *
939  * For example, Mac OS X 10.4.9 has API version 1080400.
940  * This allows applications to do simple greater-than and less-than comparisons:
941  * e.g. an application that requires at least API version 1080400 can check:
942  *   if (version >= 1080400) ...
943  *
944  * Example usage:
945  * uint32_t version;
946  * uint32_t size = sizeof(version);
947  * DNSServiceErrorType err = DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &version, &size);
948  * if (!err) printf("DNS_SD API version is %d.%d\n", version / 10000, version / 100 % 100);
949  */
950 
951 #define kDNSServiceProperty_DaemonVersion "DaemonVersion"
952 
953 /*********************************************************************************************
954 *
955 * Unix Domain Socket access, DNSServiceRef deallocation, and data processing functions
956 *
957 *********************************************************************************************/
958 
959 /* DNSServiceRefSockFD()
960  *
961  * Access underlying Unix domain socket for an initialized DNSServiceRef.
962  * The DNS Service Discovery implementation uses this socket to communicate between the client and
963  * the daemon. The application MUST NOT directly read from or write to this socket.
964  * Access to the socket is provided so that it can be used as a kqueue event source, a CFRunLoop
965  * event source, in a select() loop, etc. When the underlying event management subsystem (kqueue/
966  * select/CFRunLoop etc.) indicates to the client that data is available for reading on the
967  * socket, the client should call DNSServiceProcessResult(), which will extract the daemon's
968  * reply from the socket, and pass it to the appropriate application callback. By using a run
969  * loop or select(), results from the daemon can be processed asynchronously. Alternatively,
970  * a client can choose to fork a thread and have it loop calling "DNSServiceProcessResult(ref);"
971  * If DNSServiceProcessResult() is called when no data is available for reading on the socket, it
972  * will block until data does become available, and then process the data and return to the caller.
973  * The application is responsible for checking the return value of DNSServiceProcessResult()
974  * to determine if the socket is valid and if it should continue to process data on the socket.
975  * When data arrives on the socket, the client is responsible for calling DNSServiceProcessResult(ref)
976  * in a timely fashion -- if the client allows a large backlog of data to build up the daemon
977  * may terminate the connection.
978  *
979  * sdRef:           A DNSServiceRef initialized by any of the DNSService calls.
980  *
981  * return value:    The DNSServiceRef's underlying socket descriptor, or -1 on
982  *                  error.
983  */
984 
985 DNSSD_EXPORT
986 dnssd_sock_t DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
987 
988 
989 /* DNSServiceProcessResult()
990  *
991  * Read a reply from the daemon, calling the appropriate application callback. This call will
992  * block until the daemon's response is received. Use DNSServiceRefSockFD() in
993  * conjunction with a run loop or select() to determine the presence of a response from the
994  * server before calling this function to process the reply without blocking. Call this function
995  * at any point if it is acceptable to block until the daemon's response arrives. Note that the
996  * client is responsible for ensuring that DNSServiceProcessResult() is called whenever there is
997  * a reply from the daemon - the daemon may terminate its connection with a client that does not
998  * process the daemon's responses.
999  *
1000  * sdRef:           A DNSServiceRef initialized by any of the DNSService calls
1001  *                  that take a callback parameter.
1002  *
1003  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns
1004  *                  an error code indicating the specific failure that occurred.
1005  */
1006 
1007 DNSSD_EXPORT
1008 DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef);
1009 
1010 
1011 /* DNSServiceRefDeallocate()
1012  *
1013  * Terminate a connection with the daemon and free memory associated with the DNSServiceRef.
1014  * Any services or records registered with this DNSServiceRef will be deregistered. Any
1015  * Browse, Resolve, or Query operations called with this reference will be terminated.
1016  *
1017  * Note: If the reference's underlying socket is used in a run loop or select() call, it should
1018  * be removed BEFORE DNSServiceRefDeallocate() is called, as this function closes the reference's
1019  * socket.
1020  *
1021  * Note: If the reference was initialized with DNSServiceCreateConnection(), any DNSRecordRefs
1022  * created via this reference will be invalidated by this call - the resource records are
1023  * deregistered, and their DNSRecordRefs may not be used in subsequent functions. Similarly,
1024  * if the reference was initialized with DNSServiceRegister, and an extra resource record was
1025  * added to the service via DNSServiceAddRecord(), the DNSRecordRef created by the Add() call
1026  * is invalidated when this function is called - the DNSRecordRef may not be used in subsequent
1027  * functions.
1028  *
1029  * If the reference was passed to DNSServiceSetDispatchQueue(), DNSServiceRefDeallocate() must
1030  * be called on the same queue originally passed as an argument to DNSServiceSetDispatchQueue().
1031  *
1032  * Note: This call is to be used only with the DNSServiceRef defined by this API.
1033  *
1034  * sdRef:           A DNSServiceRef initialized by any of the DNSService calls.
1035  *
1036  */
1037 
1038 DNSSD_EXPORT
1039 void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef);
1040 
1041 
1042 /*********************************************************************************************
1043 *
1044 * Domain Enumeration
1045 *
1046 *********************************************************************************************/
1047 
1048 /* DNSServiceEnumerateDomains()
1049  *
1050  * Asynchronously enumerate domains available for browsing and registration.
1051  *
1052  * The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains
1053  * are to be found.
1054  *
1055  * Note that the names returned are (like all of DNS-SD) UTF-8 strings,
1056  * and are escaped using standard DNS escaping rules.
1057  * (See "Notes on DNS Name Escaping" earlier in this file for more details.)
1058  * A graphical browser displaying a hierarchical tree-structured view should cut
1059  * the names at the bare dots to yield individual labels, then de-escape each
1060  * label according to the escaping rules, and then display the resulting UTF-8 text.
1061  *
1062  * DNSServiceDomainEnumReply Callback Parameters:
1063  *
1064  * sdRef:           The DNSServiceRef initialized by DNSServiceEnumerateDomains().
1065  *
1066  * flags:           Possible values are:
1067  *                  kDNSServiceFlagsMoreComing
1068  *                  kDNSServiceFlagsAdd
1069  *                  kDNSServiceFlagsDefault
1070  *
1071  * interfaceIndex:  Specifies the interface on which the domain exists. (The index for a given
1072  *                  interface is determined via the if_nametoindex() family of calls.)
1073  *
1074  * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise indicates
1075  *                  the failure that occurred (other parameters are undefined if errorCode is nonzero).
1076  *
1077  * replyDomain:     The name of the domain.
1078  *
1079  * context:         The context pointer passed to DNSServiceEnumerateDomains.
1080  *
1081  */
1082 
1083 typedef void (DNSSD_API *DNSServiceDomainEnumReply)
1084 (
1085     DNSServiceRef sdRef,
1086     DNSServiceFlags flags,
1087     uint32_t interfaceIndex,
1088     DNSServiceErrorType errorCode,
1089     const char                          *replyDomain,
1090     void                                *context
1091 );
1092 
1093 
1094 /* DNSServiceEnumerateDomains() Parameters:
1095  *
1096  * sdRef:           A pointer to an uninitialized DNSServiceRef
1097  *                  (or, if the kDNSServiceFlagsShareConnection flag is used,
1098  *                  a copy of the shared connection reference that is to be used).
1099  *                  If the call succeeds then it initializes (or updates) the DNSServiceRef,
1100  *                  returns kDNSServiceErr_NoError, and the enumeration operation
1101  *                  will remain active indefinitely until the client terminates it
1102  *                  by passing this DNSServiceRef to DNSServiceRefDeallocate()
1103  *                  (or by closing the underlying shared connection, if used).
1104  *
1105  * flags:           Possible values are:
1106  *                  kDNSServiceFlagsShareConnection to use a shared connection.
1107  *                  kDNSServiceFlagsBrowseDomains to enumerate domains recommended for browsing.
1108  *                  kDNSServiceFlagsRegistrationDomains to enumerate domains recommended
1109  *                  for registration.
1110  *
1111  * interfaceIndex:  If non-zero, specifies the interface on which to look for domains.
1112  *                  (the index for a given interface is determined via the if_nametoindex()
1113  *                  family of calls.) Most applications will pass 0 to enumerate domains on
1114  *                  all interfaces. See "Constants for specifying an interface index" for more details.
1115  *
1116  * callBack:        The function to be called when a domain is found or the call asynchronously
1117  *                  fails.
1118  *
1119  * context:         An application context pointer which is passed to the callback function
1120  *                  (may be NULL).
1121  *
1122  * return value:    Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
1123  *                  errors are delivered to the callback), otherwise returns an error code indicating
1124  *                  the error that occurred (the callback is not invoked and the DNSServiceRef
1125  *                  is not initialized).
1126  */
1127 
1128 DNSSD_EXPORT
1129 DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
1130 (
1131     DNSServiceRef                       *sdRef,
1132     DNSServiceFlags flags,
1133     uint32_t interfaceIndex,
1134     DNSServiceDomainEnumReply callBack,
1135     void                                *context  /* may be NULL */
1136 );
1137 
1138 
1139 /*********************************************************************************************
1140 *
1141 *  Service Registration
1142 *
1143 *********************************************************************************************/
1144 
1145 /* Register a service that is discovered via Browse() and Resolve() calls.
1146  *
1147  * DNSServiceRegisterReply() Callback Parameters:
1148  *
1149  * sdRef:           The DNSServiceRef initialized by DNSServiceRegister().
1150  *
1151  * flags:           When a name is successfully registered, the callback will be
1152  *                  invoked with the kDNSServiceFlagsAdd flag set. When Wide-Area
1153  *                  DNS-SD is in use, it is possible for a single service to get
1154  *                  more than one success callback (e.g. one in the "local" multicast
1155  *                  DNS domain, and another in a wide-area unicast DNS domain).
1156  *                  If a successfully-registered name later suffers a name conflict
1157  *                  or similar problem and has to be deregistered, the callback will
1158  *                  be invoked with the kDNSServiceFlagsAdd flag not set. The callback
1159  *                  is *not* invoked in the case where the caller explicitly terminates
1160  *                  the service registration by calling DNSServiceRefDeallocate(ref);
1161  *
1162  * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
1163  *                  indicate the failure that occurred (including name conflicts,
1164  *                  if the kDNSServiceFlagsNoAutoRename flag was used when registering.)
1165  *                  Other parameters are undefined if errorCode is nonzero.
1166  *
1167  * name:            The service name registered (if the application did not specify a name in
1168  *                  DNSServiceRegister(), this indicates what name was automatically chosen).
1169  *
1170  * regtype:         The type of service registered, as it was passed to the callout.
1171  *
1172  * domain:          The domain on which the service was registered (if the application did not
1173  *                  specify a domain in DNSServiceRegister(), this indicates the default domain
1174  *                  on which the service was registered).
1175  *
1176  * context:         The context pointer that was passed to the callout.
1177  *
1178  */
1179 
1180 typedef void (DNSSD_API *DNSServiceRegisterReply)
1181 (
1182     DNSServiceRef sdRef,
1183     DNSServiceFlags flags,
1184     DNSServiceErrorType errorCode,
1185     const char                          *name,
1186     const char                          *regtype,
1187     const char                          *domain,
1188     void                                *context
1189 );
1190 
1191 
1192 /* DNSServiceRegister() Parameters:
1193  *
1194  * sdRef:           A pointer to an uninitialized DNSServiceRef
1195  *                  (or, if the kDNSServiceFlagsShareConnection flag is used,
1196  *                  a copy of the shared connection reference that is to be used).
1197  *                  If the call succeeds then it initializes (or updates) the DNSServiceRef,
1198  *                  returns kDNSServiceErr_NoError, and the service registration
1199  *                  will remain active indefinitely until the client terminates it
1200  *                  by passing this DNSServiceRef to DNSServiceRefDeallocate()
1201  *                  (or by closing the underlying shared connection, if used).
1202  *
1203  * flags:           Possible values are:
1204  *                  kDNSServiceFlagsShareConnection to use a shared connection.
1205  *                  Other flags indicate the renaming behavior on name conflict
1206  *                  (not required for most applications).
1207  *                  See flag definitions above for details.
1208  *
1209  * interfaceIndex:  If non-zero, specifies the interface on which to register the service
1210  *                  (the index for a given interface is determined via the if_nametoindex()
1211  *                  family of calls.) Most applications will pass 0 to register on all
1212  *                  available interfaces. See "Constants for specifying an interface index" for more details.
1213  *
1214  * name:            If non-NULL, specifies the service name to be registered.
1215  *                  Most applications will not specify a name, in which case the computer
1216  *                  name is used (this name is communicated to the client via the callback).
1217  *                  If a name is specified, it must be 1-63 bytes of UTF-8 text.
1218  *                  If the name is longer than 63 bytes it will be automatically truncated
1219  *                  to a legal length, unless the NoAutoRename flag is set,
1220  *                  in which case kDNSServiceErr_BadParam will be returned.
1221  *
1222  * regtype:         The service type followed by the protocol, separated by a dot
1223  *                  (e.g. "_ftp._tcp"). The service type must be an underscore, followed
1224  *                  by 1-15 characters, which may be letters, digits, or hyphens.
1225  *                  The transport protocol must be "_tcp" or "_udp". New service types
1226  *                  should be registered at <http://www.dns-sd.org/ServiceTypes.html>.
1227  *
1228  *                  Additional subtypes of the primary service type (where a service
1229  *                  type has defined subtypes) follow the primary service type in a
1230  *                  comma-separated list, with no additional spaces, e.g.
1231  *                      "_primarytype._tcp,_subtype1,_subtype2,_subtype3"
1232  *                  Subtypes provide a mechanism for filtered browsing: A client browsing
1233  *                  for "_primarytype._tcp" will discover all instances of this type;
1234  *                  a client browsing for "_primarytype._tcp,_subtype2" will discover only
1235  *                  those instances that were registered with "_subtype2" in their list of
1236  *                  registered subtypes.
1237  *
1238  *                  The subtype mechanism can be illustrated with some examples using the
1239  *                  dns-sd command-line tool:
1240  *
1241  *                  % dns-sd -R Simple _test._tcp "" 1001 &
1242  *                  % dns-sd -R Better _test._tcp,HasFeatureA "" 1002 &
1243  *                  % dns-sd -R Best   _test._tcp,HasFeatureA,HasFeatureB "" 1003 &
1244  *
1245  *                  Now:
1246  *                  % dns-sd -B _test._tcp             # will find all three services
1247  *                  % dns-sd -B _test._tcp,HasFeatureA # finds "Better" and "Best"
1248  *                  % dns-sd -B _test._tcp,HasFeatureB # finds only "Best"
1249  *
1250  *                  Subtype labels may be up to 63 bytes long, and may contain any eight-
1251  *                  bit byte values, including zero bytes. However, due to the nature of
1252  *                  using a C-string-based API, conventional DNS escaping must be used for
1253  *                  dots ('.'), commas (','), backslashes ('\') and zero bytes, as shown below:
1254  *
1255  *                  % dns-sd -R Test '_test._tcp,s\.one,s\,two,s\\three,s\000four' local 123
1256  *
1257  * domain:          If non-NULL, specifies the domain on which to advertise the service.
1258  *                  Most applications will not specify a domain, instead automatically
1259  *                  registering in the default domain(s).
1260  *
1261  * host:            If non-NULL, specifies the SRV target host name. Most applications
1262  *                  will not specify a host, instead automatically using the machine's
1263  *                  default host name(s). Note that specifying a non-NULL host does NOT
1264  *                  create an address record for that host - the application is responsible
1265  *                  for ensuring that the appropriate address record exists, or creating it
1266  *                  via DNSServiceRegisterRecord().
1267  *
1268  * port:            The port, in network byte order, on which the service accepts connections.
1269  *                  Pass 0 for a "placeholder" service (i.e. a service that will not be discovered
1270  *                  by browsing, but will cause a name conflict if another client tries to
1271  *                  register that same name). Most clients will not use placeholder services.
1272  *
1273  * txtLen:          The length of the txtRecord, in bytes. Must be zero if the txtRecord is NULL.
1274  *
1275  * txtRecord:       The TXT record rdata. A non-NULL txtRecord MUST be a properly formatted DNS
1276  *                  TXT record, i.e. <length byte> <data> <length byte> <data> ...
1277  *                  Passing NULL for the txtRecord is allowed as a synonym for txtLen=1, txtRecord="",
1278  *                  i.e. it creates a TXT record of length one containing a single empty string.
1279  *                  RFC 1035 doesn't allow a TXT record to contain *zero* strings, so a single empty
1280  *                  string is the smallest legal DNS TXT record.
1281  *                  As with the other parameters, the DNSServiceRegister call copies the txtRecord
1282  *                  data; e.g. if you allocated the storage for the txtRecord parameter with malloc()
1283  *                  then you can safely free that memory right after the DNSServiceRegister call returns.
1284  *
1285  * callBack:        The function to be called when the registration completes or asynchronously
1286  *                  fails. The client MAY pass NULL for the callback -  The client will NOT be notified
1287  *                  of the default values picked on its behalf, and the client will NOT be notified of any
1288  *                  asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
1289  *                  of the service. The client may NOT pass the NoAutoRename flag if the callback is NULL.
1290  *                  The client may still deregister the service at any time via DNSServiceRefDeallocate().
1291  *
1292  * context:         An application context pointer which is passed to the callback function
1293  *                  (may be NULL).
1294  *
1295  * return value:    Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
1296  *                  errors are delivered to the callback), otherwise returns an error code indicating
1297  *                  the error that occurred (the callback is never invoked and the DNSServiceRef
1298  *                  is not initialized).
1299  */
1300 
1301 DNSSD_EXPORT
1302 DNSServiceErrorType DNSSD_API DNSServiceRegister
1303 (
1304     DNSServiceRef                       *sdRef,
1305     DNSServiceFlags flags,
1306     uint32_t interfaceIndex,
1307     const char                          *name,         /* may be NULL */
1308     const char                          *regtype,
1309     const char                          *domain,       /* may be NULL */
1310     const char                          *host,         /* may be NULL */
1311     uint16_t port,                                     /* In network byte order */
1312     uint16_t txtLen,
1313     const void                          *txtRecord,    /* may be NULL */
1314     DNSServiceRegisterReply callBack,                  /* may be NULL */
1315     void                                *context       /* may be NULL */
1316 );
1317 
1318 
1319 /* DNSServiceAddRecord()
1320  *
1321  * Add a record to a registered service. The name of the record will be the same as the
1322  * registered service's name.
1323  * The record can later be updated or deregistered by passing the RecordRef initialized
1324  * by this function to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
1325  *
1326  * Note that the DNSServiceAddRecord/UpdateRecord/RemoveRecord are *NOT* thread-safe
1327  * with respect to a single DNSServiceRef. If you plan to have multiple threads
1328  * in your program simultaneously add, update, or remove records from the same
1329  * DNSServiceRef, then it's the caller's responsibility to use a mutex lock
1330  * or take similar appropriate precautions to serialize those calls.
1331  *
1332  * Parameters;
1333  *
1334  * sdRef:           A DNSServiceRef initialized by DNSServiceRegister().
1335  *
1336  * RecordRef:       A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
1337  *                  call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
1338  *                  If the above DNSServiceRef is passed to DNSServiceRefDeallocate(), RecordRef is also
1339  *                  invalidated and may not be used further.
1340  *
1341  * flags:           Currently ignored, reserved for future use.
1342  *
1343  * rrtype:          The type of the record (e.g. kDNSServiceType_TXT, kDNSServiceType_SRV, etc)
1344  *
1345  * rdlen:           The length, in bytes, of the rdata.
1346  *
1347  * rdata:           The raw rdata to be contained in the added resource record.
1348  *
1349  * ttl:             The time to live of the resource record, in seconds.
1350  *                  Most clients should pass 0 to indicate that the system should
1351  *                  select a sensible default value.
1352  *
1353  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
1354  *                  error code indicating the error that occurred (the RecordRef is not initialized).
1355  */
1356 
1357 DNSSD_EXPORT
1358 DNSServiceErrorType DNSSD_API DNSServiceAddRecord
1359 (
1360     DNSServiceRef sdRef,
1361     DNSRecordRef                        *RecordRef,
1362     DNSServiceFlags flags,
1363     uint16_t rrtype,
1364     uint16_t rdlen,
1365     const void                          *rdata,
1366     uint32_t ttl
1367 );
1368 
1369 
1370 /* DNSServiceUpdateRecord
1371  *
1372  * Update a registered resource record. The record must either be:
1373  *   - The primary txt record of a service registered via DNSServiceRegister()
1374  *   - A record added to a registered service via DNSServiceAddRecord()
1375  *   - An individual record registered by DNSServiceRegisterRecord()
1376  *
1377  * Parameters:
1378  *
1379  * sdRef:           A DNSServiceRef that was initialized by DNSServiceRegister()
1380  *                  or DNSServiceCreateConnection().
1381  *
1382  * RecordRef:       A DNSRecordRef initialized by DNSServiceAddRecord, or NULL to update the
1383  *                  service's primary txt record.
1384  *
1385  * flags:           Currently ignored, reserved for future use.
1386  *
1387  * rdlen:           The length, in bytes, of the new rdata.
1388  *
1389  * rdata:           The new rdata to be contained in the updated resource record.
1390  *
1391  * ttl:             The time to live of the updated resource record, in seconds.
1392  *                  Most clients should pass 0 to indicate that the system should
1393  *                  select a sensible default value.
1394  *
1395  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
1396  *                  error code indicating the error that occurred.
1397  */
1398 
1399 DNSSD_EXPORT
1400 DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
1401 (
1402     DNSServiceRef sdRef,
1403     DNSRecordRef RecordRef,                            /* may be NULL */
1404     DNSServiceFlags flags,
1405     uint16_t rdlen,
1406     const void                          *rdata,
1407     uint32_t ttl
1408 );
1409 
1410 
1411 /* DNSServiceRemoveRecord
1412  *
1413  * Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
1414  * a record registered individually via DNSServiceRegisterRecord().
1415  *
1416  * Parameters:
1417  *
1418  * sdRef:           A DNSServiceRef initialized by DNSServiceRegister() (if the
1419  *                  record being removed was registered via DNSServiceAddRecord()) or by
1420  *                  DNSServiceCreateConnection() (if the record being removed was registered via
1421  *                  DNSServiceRegisterRecord()).
1422  *
1423  * recordRef:       A DNSRecordRef initialized by a successful call to DNSServiceAddRecord()
1424  *                  or DNSServiceRegisterRecord().
1425  *
1426  * flags:           Currently ignored, reserved for future use.
1427  *
1428  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
1429  *                  error code indicating the error that occurred.
1430  */
1431 
1432 DNSSD_EXPORT
1433 DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
1434 (
1435     DNSServiceRef sdRef,
1436     DNSRecordRef RecordRef,
1437     DNSServiceFlags flags
1438 );
1439 
1440 
1441 /*********************************************************************************************
1442 *
1443 *  Service Discovery
1444 *
1445 *********************************************************************************************/
1446 
1447 /* Browse for instances of a service.
1448  *
1449  * DNSServiceBrowseReply() Parameters:
1450  *
1451  * sdRef:           The DNSServiceRef initialized by DNSServiceBrowse().
1452  *
1453  * flags:           Possible values are kDNSServiceFlagsMoreComing and kDNSServiceFlagsAdd.
1454  *                  See flag definitions for details.
1455  *
1456  * interfaceIndex:  The interface on which the service is advertised. This index should
1457  *                  be passed to DNSServiceResolve() when resolving the service.
1458  *
1459  * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise will
1460  *                  indicate the failure that occurred. Other parameters are undefined if
1461  *                  the errorCode is nonzero.
1462  *
1463  * serviceName:     The discovered service name. This name should be displayed to the user,
1464  *                  and stored for subsequent use in the DNSServiceResolve() call.
1465  *
1466  * regtype:         The service type, which is usually (but not always) the same as was passed
1467  *                  to DNSServiceBrowse(). One case where the discovered service type may
1468  *                  not be the same as the requested service type is when using subtypes:
1469  *                  The client may want to browse for only those ftp servers that allow
1470  *                  anonymous connections. The client will pass the string "_ftp._tcp,_anon"
1471  *                  to DNSServiceBrowse(), but the type of the service that's discovered
1472  *                  is simply "_ftp._tcp". The regtype for each discovered service instance
1473  *                  should be stored along with the name, so that it can be passed to
1474  *                  DNSServiceResolve() when the service is later resolved.
1475  *
1476  * domain:          The domain of the discovered service instance. This may or may not be the
1477  *                  same as the domain that was passed to DNSServiceBrowse(). The domain for each
1478  *                  discovered service instance should be stored along with the name, so that
1479  *                  it can be passed to DNSServiceResolve() when the service is later resolved.
1480  *
1481  * context:         The context pointer that was passed to the callout.
1482  *
1483  */
1484 
1485 typedef void (DNSSD_API *DNSServiceBrowseReply)
1486 (
1487     DNSServiceRef sdRef,
1488     DNSServiceFlags flags,
1489     uint32_t interfaceIndex,
1490     DNSServiceErrorType errorCode,
1491     const char                          *serviceName,
1492     const char                          *regtype,
1493     const char                          *replyDomain,
1494     void                                *context
1495 );
1496 
1497 
1498 /* DNSServiceBrowse() Parameters:
1499  *
1500  * sdRef:           A pointer to an uninitialized DNSServiceRef
1501  *                  (or, if the kDNSServiceFlagsShareConnection flag is used,
1502  *                  a copy of the shared connection reference that is to be used).
1503  *                  If the call succeeds then it initializes (or updates) the DNSServiceRef,
1504  *                  returns kDNSServiceErr_NoError, and the browse operation
1505  *                  will remain active indefinitely until the client terminates it
1506  *                  by passing this DNSServiceRef to DNSServiceRefDeallocate()
1507  *                  (or by closing the underlying shared connection, if used).
1508  *
1509  * flags:           Possible values are:
1510  *                  kDNSServiceFlagsShareConnection to use a shared connection.
1511  *
1512  * interfaceIndex:  If non-zero, specifies the interface on which to browse for services
1513  *                  (the index for a given interface is determined via the if_nametoindex()
1514  *                  family of calls.) Most applications will pass 0 to browse on all available
1515  *                  interfaces. See "Constants for specifying an interface index" for more details.
1516  *
1517  * regtype:         The service type being browsed for followed by the protocol, separated by a
1518  *                  dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
1519  *                  A client may optionally specify a single subtype to perform filtered browsing:
1520  *                  e.g. browsing for "_primarytype._tcp,_subtype" will discover only those
1521  *                  instances of "_primarytype._tcp" that were registered specifying "_subtype"
1522  *                  in their list of registered subtypes.
1523  *
1524  * domain:          If non-NULL, specifies the domain on which to browse for services.
1525  *                  Most applications will not specify a domain, instead browsing on the
1526  *                  default domain(s).
1527  *
1528  * callBack:        The function to be called when an instance of the service being browsed for
1529  *                  is found, or if the call asynchronously fails.
1530  *
1531  * context:         An application context pointer which is passed to the callback function
1532  *                  (may be NULL).
1533  *
1534  * return value:    Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
1535  *                  errors are delivered to the callback), otherwise returns an error code indicating
1536  *                  the error that occurred (the callback is not invoked and the DNSServiceRef
1537  *                  is not initialized).
1538  */
1539 
1540 DNSSD_EXPORT
1541 DNSServiceErrorType DNSSD_API DNSServiceBrowse
1542 (
1543     DNSServiceRef                       *sdRef,
1544     DNSServiceFlags flags,
1545     uint32_t interfaceIndex,
1546     const char                          *regtype,
1547     const char                          *domain,    /* may be NULL */
1548     DNSServiceBrowseReply callBack,
1549     void                                *context    /* may be NULL */
1550 );
1551 
1552 
1553 /* DNSServiceResolve()
1554  *
1555  * Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and
1556  * txt record.
1557  *
1558  * Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use
1559  * DNSServiceQueryRecord() instead, as it is more efficient for this task.
1560  *
1561  * Note: When the desired results have been returned, the client MUST terminate the resolve by calling
1562  * DNSServiceRefDeallocate().
1563  *
1564  * Note: DNSServiceResolve() behaves correctly for typical services that have a single SRV record
1565  * and a single TXT record. To resolve non-standard services with multiple SRV or TXT records,
1566  * DNSServiceQueryRecord() should be used.
1567  *
1568  * DNSServiceResolveReply Callback Parameters:
1569  *
1570  * sdRef:           The DNSServiceRef initialized by DNSServiceResolve().
1571  *
1572  * flags:           Possible values: kDNSServiceFlagsMoreComing
1573  *
1574  * interfaceIndex:  The interface on which the service was resolved.
1575  *
1576  * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise will
1577  *                  indicate the failure that occurred. Other parameters are undefined if
1578  *                  the errorCode is nonzero.
1579  *
1580  * fullname:        The full service domain name, in the form <servicename>.<protocol>.<domain>.
1581  *                  (This name is escaped following standard DNS rules, making it suitable for
1582  *                  passing to standard system DNS APIs such as res_query(), or to the
1583  *                  special-purpose functions included in this API that take fullname parameters.
1584  *                  See "Notes on DNS Name Escaping" earlier in this file for more details.)
1585  *
1586  * hosttarget:      The target hostname of the machine providing the service. This name can
1587  *                  be passed to functions like gethostbyname() to identify the host's IP address.
1588  *
1589  * port:            The port, in network byte order, on which connections are accepted for this service.
1590  *
1591  * txtLen:          The length of the txt record, in bytes.
1592  *
1593  * txtRecord:       The service's primary txt record, in standard txt record format.
1594  *
1595  * context:         The context pointer that was passed to the callout.
1596  *
1597  * NOTE: In earlier versions of this header file, the txtRecord parameter was declared "const char *"
1598  * This is incorrect, since it contains length bytes which are values in the range 0 to 255, not -128 to +127.
1599  * Depending on your compiler settings, this change may cause signed/unsigned mismatch warnings.
1600  * These should be fixed by updating your own callback function definition to match the corrected
1601  * function signature using "const unsigned char *txtRecord". Making this change may also fix inadvertent
1602  * bugs in your callback function, where it could have incorrectly interpreted a length byte with value 250
1603  * as being -6 instead, with various bad consequences ranging from incorrect operation to software crashes.
1604  * If you need to maintain portable code that will compile cleanly with both the old and new versions of
1605  * this header file, you should update your callback function definition to use the correct unsigned value,
1606  * and then in the place where you pass your callback function to DNSServiceResolve(), use a cast to eliminate
1607  * the compiler warning, e.g.:
1608  *   DNSServiceResolve(sd, flags, index, name, regtype, domain, (DNSServiceResolveReply)MyCallback, context);
1609  * This will ensure that your code compiles cleanly without warnings (and more importantly, works correctly)
1610  * with both the old header and with the new corrected version.
1611  *
1612  */
1613 
1614 typedef void (DNSSD_API *DNSServiceResolveReply)
1615 (
1616     DNSServiceRef sdRef,
1617     DNSServiceFlags flags,
1618     uint32_t interfaceIndex,
1619     DNSServiceErrorType errorCode,
1620     const char                          *fullname,
1621     const char                          *hosttarget,
1622     uint16_t port,                                   /* In network byte order */
1623     uint16_t txtLen,
1624     const unsigned char                 *txtRecord,
1625     void                                *context
1626 );
1627 
1628 
1629 /* DNSServiceResolve() Parameters
1630  *
1631  * sdRef:           A pointer to an uninitialized DNSServiceRef
1632  *                  (or, if the kDNSServiceFlagsShareConnection flag is used,
1633  *                  a copy of the shared connection reference that is to be used).
1634  *                  If the call succeeds then it initializes (or updates) the DNSServiceRef,
1635  *                  returns kDNSServiceErr_NoError, and the resolve operation
1636  *                  will remain active indefinitely until the client terminates it
1637  *                  by passing this DNSServiceRef to DNSServiceRefDeallocate()
1638  *                  (or by closing the underlying shared connection, if used).
1639  *
1640  * flags:           Possible values are:
1641  *                  kDNSServiceFlagsShareConnection to use a shared connection.
1642  *                  Specifying kDNSServiceFlagsForceMulticast will cause query to be
1643  *                  performed with a link-local mDNS query, even if the name is an
1644  *                  apparently non-local name (i.e. a name not ending in ".local.")
1645  *
1646  * interfaceIndex:  The interface on which to resolve the service. If this resolve call is
1647  *                  as a result of a currently active DNSServiceBrowse() operation, then the
1648  *                  interfaceIndex should be the index reported in the DNSServiceBrowseReply
1649  *                  callback. If this resolve call is using information previously saved
1650  *                  (e.g. in a preference file) for later use, then use interfaceIndex 0, because
1651  *                  the desired service may now be reachable via a different physical interface.
1652  *                  See "Constants for specifying an interface index" for more details.
1653  *
1654  * name:            The name of the service instance to be resolved, as reported to the
1655  *                  DNSServiceBrowseReply() callback.
1656  *
1657  * regtype:         The type of the service instance to be resolved, as reported to the
1658  *                  DNSServiceBrowseReply() callback.
1659  *
1660  * domain:          The domain of the service instance to be resolved, as reported to the
1661  *                  DNSServiceBrowseReply() callback.
1662  *
1663  * callBack:        The function to be called when a result is found, or if the call
1664  *                  asynchronously fails.
1665  *
1666  * context:         An application context pointer which is passed to the callback function
1667  *                  (may be NULL).
1668  *
1669  * return value:    Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
1670  *                  errors are delivered to the callback), otherwise returns an error code indicating
1671  *                  the error that occurred (the callback is never invoked and the DNSServiceRef
1672  *                  is not initialized).
1673  */
1674 
1675 DNSSD_EXPORT
1676 DNSServiceErrorType DNSSD_API DNSServiceResolve
1677 (
1678     DNSServiceRef                       *sdRef,
1679     DNSServiceFlags flags,
1680     uint32_t interfaceIndex,
1681     const char                          *name,
1682     const char                          *regtype,
1683     const char                          *domain,
1684     DNSServiceResolveReply callBack,
1685     void                                *context  /* may be NULL */
1686 );
1687 
1688 
1689 /*********************************************************************************************
1690 *
1691 *  Querying Individual Specific Records
1692 *
1693 *********************************************************************************************/
1694 
1695 /* DNSServiceQueryRecord
1696  *
1697  * Query for an arbitrary DNS record.
1698  *
1699  * DNSServiceQueryRecordReply() Callback Parameters:
1700  *
1701  * sdRef:           The DNSServiceRef initialized by DNSServiceQueryRecord().
1702  *
1703  * flags:           Possible values are kDNSServiceFlagsMoreComing and
1704  *                  kDNSServiceFlagsAdd. The Add flag is NOT set for PTR records
1705  *                  with a ttl of 0, i.e. "Remove" events.
1706  *
1707  * interfaceIndex:  The interface on which the query was resolved (the index for a given
1708  *                  interface is determined via the if_nametoindex() family of calls).
1709  *                  See "Constants for specifying an interface index" for more details.
1710  *
1711  * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
1712  *                  indicate the failure that occurred. Other parameters are undefined if
1713  *                  errorCode is nonzero.
1714  *
1715  * fullname:        The resource record's full domain name.
1716  *
1717  * rrtype:          The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
1718  *
1719  * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
1720  *
1721  * rdlen:           The length, in bytes, of the resource record rdata.
1722  *
1723  * rdata:           The raw rdata of the resource record.
1724  *
1725  * ttl:             If the client wishes to cache the result for performance reasons,
1726  *                  the TTL indicates how long the client may legitimately hold onto
1727  *                  this result, in seconds. After the TTL expires, the client should
1728  *                  consider the result no longer valid, and if it requires this data
1729  *                  again, it should be re-fetched with a new query. Of course, this
1730  *                  only applies to clients that cancel the asynchronous operation when
1731  *                  they get a result. Clients that leave the asynchronous operation
1732  *                  running can safely assume that the data remains valid until they
1733  *                  get another callback telling them otherwise. The ttl value is not
1734  *                  updated when the daemon answers from the cache, hence relying on
1735  *                  the accuracy of the ttl value is not recommended.
1736  *
1737  * context:         The context pointer that was passed to the callout.
1738  *
1739  */
1740 
1741 typedef void (DNSSD_API *DNSServiceQueryRecordReply)
1742 (
1743     DNSServiceRef sdRef,
1744     DNSServiceFlags flags,
1745     uint32_t interfaceIndex,
1746     DNSServiceErrorType errorCode,
1747     const char                          *fullname,
1748     uint16_t rrtype,
1749     uint16_t rrclass,
1750     uint16_t rdlen,
1751     const void                          *rdata,
1752     uint32_t ttl,
1753     void                                *context
1754 );
1755 
1756 
1757 /* DNSServiceQueryRecord() Parameters:
1758  *
1759  * sdRef:           A pointer to an uninitialized DNSServiceRef
1760  *                  (or, if the kDNSServiceFlagsShareConnection flag is used,
1761  *                  a copy of the shared connection reference that is to be used).
1762  *                  If the call succeeds then it initializes (or updates) the DNSServiceRef,
1763  *                  returns kDNSServiceErr_NoError, and the query operation
1764  *                  will remain active indefinitely until the client terminates it
1765  *                  by passing this DNSServiceRef to DNSServiceRefDeallocate()
1766  *                  (or by closing the underlying shared connection, if used).
1767  *
1768  * flags:           Possible values are:
1769  *                  kDNSServiceFlagsShareConnection to use a shared connection.
1770  *                  kDNSServiceFlagsForceMulticast or kDNSServiceFlagsLongLivedQuery.
1771  *                  Pass kDNSServiceFlagsLongLivedQuery to create a "long-lived" unicast
1772  *                  query to a unicast DNS server that implements the protocol. This flag
1773  *                  has no effect on link-local multicast queries.
1774  *
1775  * interfaceIndex:  If non-zero, specifies the interface on which to issue the query
1776  *                  (the index for a given interface is determined via the if_nametoindex()
1777  *                  family of calls.) Passing 0 causes the name to be queried for on all
1778  *                  interfaces. See "Constants for specifying an interface index" for more details.
1779  *
1780  * fullname:        The full domain name of the resource record to be queried for.
1781  *
1782  * rrtype:          The numerical type of the resource record to be queried for
1783  *                  (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
1784  *
1785  * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
1786  *
1787  * callBack:        The function to be called when a result is found, or if the call
1788  *                  asynchronously fails.
1789  *
1790  * context:         An application context pointer which is passed to the callback function
1791  *                  (may be NULL).
1792  *
1793  * return value:    Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
1794  *                  errors are delivered to the callback), otherwise returns an error code indicating
1795  *                  the error that occurred (the callback is never invoked and the DNSServiceRef
1796  *                  is not initialized).
1797  */
1798 
1799 DNSSD_EXPORT
1800 DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
1801 (
1802     DNSServiceRef                       *sdRef,
1803     DNSServiceFlags flags,
1804     uint32_t interfaceIndex,
1805     const char                          *fullname,
1806     uint16_t rrtype,
1807     uint16_t rrclass,
1808     DNSServiceQueryRecordReply callBack,
1809     void                                *context  /* may be NULL */
1810 );
1811 
1812 
1813 /*********************************************************************************************
1814 *
1815 *  Unified lookup of both IPv4 and IPv6 addresses for a fully qualified hostname
1816 *
1817 *********************************************************************************************/
1818 
1819 /* DNSServiceGetAddrInfo
1820  *
1821  * Queries for the IP address of a hostname by using either Multicast or Unicast DNS.
1822  *
1823  * DNSServiceGetAddrInfoReply() parameters:
1824  *
1825  * sdRef:           The DNSServiceRef initialized by DNSServiceGetAddrInfo().
1826  *
1827  * flags:           Possible values are kDNSServiceFlagsMoreComing and
1828  *                  kDNSServiceFlagsAdd.
1829  *
1830  * interfaceIndex:  The interface to which the answers pertain.
1831  *
1832  * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
1833  *                  indicate the failure that occurred.  Other parameters are
1834  *                  undefined if errorCode is nonzero.
1835  *
1836  * hostname:        The fully qualified domain name of the host to be queried for.
1837  *
1838  * address:         IPv4 or IPv6 address.
1839  *
1840  * ttl:             If the client wishes to cache the result for performance reasons,
1841  *                  the TTL indicates how long the client may legitimately hold onto
1842  *                  this result, in seconds. After the TTL expires, the client should
1843  *                  consider the result no longer valid, and if it requires this data
1844  *                  again, it should be re-fetched with a new query. Of course, this
1845  *                  only applies to clients that cancel the asynchronous operation when
1846  *                  they get a result. Clients that leave the asynchronous operation
1847  *                  running can safely assume that the data remains valid until they
1848  *                  get another callback telling them otherwise. The ttl value is not
1849  *                  updated when the daemon answers from the cache, hence relying on
1850  *                  the accuracy of the ttl value is not recommended.
1851  *
1852  * context:         The context pointer that was passed to the callout.
1853  *
1854  */
1855 
1856 typedef void (DNSSD_API *DNSServiceGetAddrInfoReply)
1857 (
1858     DNSServiceRef sdRef,
1859     DNSServiceFlags flags,
1860     uint32_t interfaceIndex,
1861     DNSServiceErrorType errorCode,
1862     const char                       *hostname,
1863     const struct sockaddr            *address,
1864     uint32_t ttl,
1865     void                             *context
1866 );
1867 
1868 
1869 /* DNSServiceGetAddrInfo() Parameters:
1870  *
1871  * sdRef:           A pointer to an uninitialized DNSServiceRef
1872  *                  (or, if the kDNSServiceFlagsShareConnection flag is used,
1873  *                  a copy of the shared connection reference that is to be used).
1874  *                  If the call succeeds then it initializes (or updates) the DNSServiceRef,
1875  *                  returns kDNSServiceErr_NoError, and the address query operation
1876  *                  will remain active indefinitely until the client terminates it
1877  *                  by passing this DNSServiceRef to DNSServiceRefDeallocate()
1878  *                  (or by closing the underlying shared connection, if used).
1879  *
1880  * flags:           Possible values are:
1881  *                  kDNSServiceFlagsShareConnection to use a shared connection.
1882  *                  kDNSServiceFlagsForceMulticast
1883  *
1884  * interfaceIndex:  The interface on which to issue the query.  Passing 0 causes the query to be
1885  *                  sent on all active interfaces via Multicast or the primary interface via Unicast.
1886  *
1887  * protocol:        Pass in kDNSServiceProtocol_IPv4 to look up IPv4 addresses, or kDNSServiceProtocol_IPv6
1888  *                  to look up IPv6 addresses, or both to look up both kinds. If neither flag is
1889  *                  set, the system will apply an intelligent heuristic, which is (currently)
1890  *                  that it will attempt to look up both, except:
1891  *
1892  *                   * If "hostname" is a wide-area unicast DNS hostname (i.e. not a ".local." name)
1893  *                     but this host has no routable IPv6 address, then the call will not try to
1894  *                     look up IPv6 addresses for "hostname", since any addresses it found would be
1895  *                     unlikely to be of any use anyway. Similarly, if this host has no routable
1896  *                     IPv4 address, the call will not try to look up IPv4 addresses for "hostname".
1897  *
1898  * hostname:        The fully qualified domain name of the host to be queried for.
1899  *
1900  * callBack:        The function to be called when the query succeeds or fails asynchronously.
1901  *
1902  * context:         An application context pointer which is passed to the callback function
1903  *                  (may be NULL).
1904  *
1905  * return value:    Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
1906  *                  errors are delivered to the callback), otherwise returns an error code indicating
1907  *                  the error that occurred.
1908  */
1909 
1910 DNSSD_EXPORT
1911 DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
1912 (
1913     DNSServiceRef                    *sdRef,
1914     DNSServiceFlags flags,
1915     uint32_t interfaceIndex,
1916     DNSServiceProtocol protocol,
1917     const char                       *hostname,
1918     DNSServiceGetAddrInfoReply callBack,
1919     void                             *context          /* may be NULL */
1920 );
1921 
1922 
1923 /*********************************************************************************************
1924 *
1925 *  Special Purpose Calls:
1926 *  DNSServiceCreateConnection(), DNSServiceRegisterRecord(), DNSServiceReconfirmRecord()
1927 *  (most applications will not use these)
1928 *
1929 *********************************************************************************************/
1930 
1931 /* DNSServiceCreateConnection()
1932  *
1933  * Create a connection to the daemon allowing efficient registration of
1934  * multiple individual records.
1935  *
1936  * Parameters:
1937  *
1938  * sdRef:           A pointer to an uninitialized DNSServiceRef.
1939  *                  Deallocating the reference (via DNSServiceRefDeallocate())
1940  *                  severs the connection and cancels all operations and
1941  *                  deregisters all records registered on this connection.
1942  *
1943  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns
1944  *                  an error code indicating the specific failure that occurred
1945  *                  (in which case the DNSServiceRef is not initialized).
1946  */
1947 
1948 DNSSD_EXPORT
1949 DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef);
1950 
1951 /* DNSServiceRegisterRecord
1952  *
1953  * Register an individual resource record on a connected DNSServiceRef.
1954  *
1955  * Note that name conflicts occurring for records registered via this call must be handled
1956  * by the client in the callback.
1957  *
1958  * DNSServiceRegisterRecordReply() parameters:
1959  *
1960  * sdRef:           The connected DNSServiceRef initialized by
1961  *                  DNSServiceCreateConnection().
1962  *
1963  * RecordRef:       The DNSRecordRef initialized by DNSServiceRegisterRecord(). If the above
1964  *                  DNSServiceRef is passed to DNSServiceRefDeallocate(), this DNSRecordRef is
1965  *                  invalidated, and may not be used further.
1966  *
1967  * flags:           Currently unused, reserved for future use.
1968  *
1969  * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
1970  *                  indicate the failure that occurred (including name conflicts.)
1971  *                  Other parameters are undefined if errorCode is nonzero.
1972  *
1973  * context:         The context pointer that was passed to the callout.
1974  *
1975  */
1976 
1977 typedef void (DNSSD_API *DNSServiceRegisterRecordReply)
1978 (
1979     DNSServiceRef sdRef,
1980     DNSRecordRef RecordRef,
1981     DNSServiceFlags flags,
1982     DNSServiceErrorType errorCode,
1983     void                                *context
1984 );
1985 
1986 
1987 /* DNSServiceRegisterRecord() Parameters:
1988  *
1989  * sdRef:           A DNSServiceRef initialized by DNSServiceCreateConnection().
1990  *
1991  * RecordRef:       A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
1992  *                  call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
1993  *                  (To deregister ALL records registered on a single connected DNSServiceRef
1994  *                  and deallocate each of their corresponding DNSServiceRecordRefs, call
1995  *                  DNSServiceRefDeallocate()).
1996  *
1997  * flags:           One of either kDNSServiceFlagsShared, kDNSServiceFlagsUnique or kDNSServiceFlagsKnownUnique must be set.
1998  *
1999  * interfaceIndex:  If non-zero, specifies the interface on which to register the record
2000  *                  (the index for a given interface is determined via the if_nametoindex()
2001  *                  family of calls.) Passing 0 causes the record to be registered on all interfaces.
2002  *                  See "Constants for specifying an interface index" for more details.
2003  *
2004  * fullname:        The full domain name of the resource record.
2005  *
2006  * rrtype:          The numerical type of the resource record (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
2007  *
2008  * rrclass:         The class of the resource record (usually kDNSServiceClass_IN)
2009  *
2010  * rdlen:           Length, in bytes, of the rdata.
2011  *
2012  * rdata:           A pointer to the raw rdata, as it is to appear in the DNS record.
2013  *
2014  * ttl:             The time to live of the resource record, in seconds.
2015  *                  Most clients should pass 0 to indicate that the system should
2016  *                  select a sensible default value.
2017  *
2018  * callBack:        The function to be called when a result is found, or if the call
2019  *                  asynchronously fails (e.g. because of a name conflict.)
2020  *
2021  * context:         An application context pointer which is passed to the callback function
2022  *                  (may be NULL).
2023  *
2024  * return value:    Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
2025  *                  errors are delivered to the callback), otherwise returns an error code indicating
2026  *                  the error that occurred (the callback is never invoked and the DNSRecordRef is
2027  *                  not initialized).
2028  */
2029 
2030 DNSSD_EXPORT
2031 DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
2032 (
2033     DNSServiceRef sdRef,
2034     DNSRecordRef                        *RecordRef,
2035     DNSServiceFlags flags,
2036     uint32_t interfaceIndex,
2037     const char                          *fullname,
2038     uint16_t rrtype,
2039     uint16_t rrclass,
2040     uint16_t rdlen,
2041     const void                          *rdata,
2042     uint32_t ttl,
2043     DNSServiceRegisterRecordReply callBack,
2044     void                                *context    /* may be NULL */
2045 );
2046 
2047 
2048 /* DNSServiceReconfirmRecord
2049  *
2050  * Instruct the daemon to verify the validity of a resource record that appears
2051  * to be out of date (e.g. because TCP connection to a service's target failed.)
2052  * Causes the record to be flushed from the daemon's cache (as well as all other
2053  * daemons' caches on the network) if the record is determined to be invalid.
2054  * Use this routine conservatively. Reconfirming a record necessarily consumes
2055  * network bandwidth, so this should not be done indiscriminately.
2056  *
2057  * Parameters:
2058  *
2059  * flags:           Not currently used.
2060  *
2061  * interfaceIndex:  Specifies the interface of the record in question.
2062  *                  The caller must specify the interface.
2063  *                  This API (by design) causes increased network traffic, so it requires
2064  *                  the caller to be precise about which record should be reconfirmed.
2065  *                  It is not possible to pass zero for the interface index to perform
2066  *                  a "wildcard" reconfirmation, where *all* matching records are reconfirmed.
2067  *
2068  * fullname:        The resource record's full domain name.
2069  *
2070  * rrtype:          The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
2071  *
2072  * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
2073  *
2074  * rdlen:           The length, in bytes, of the resource record rdata.
2075  *
2076  * rdata:           The raw rdata of the resource record.
2077  *
2078  */
2079 
2080 DNSSD_EXPORT
2081 DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
2082 (
2083     DNSServiceFlags flags,
2084     uint32_t interfaceIndex,
2085     const char                         *fullname,
2086     uint16_t rrtype,
2087     uint16_t rrclass,
2088     uint16_t rdlen,
2089     const void                         *rdata
2090 );
2091 
2092 
2093 /*********************************************************************************************
2094 *
2095 *  NAT Port Mapping
2096 *
2097 *********************************************************************************************/
2098 
2099 /* DNSServiceNATPortMappingCreate
2100  *
2101  * Request a port mapping in the NAT gateway, which maps a port on the local machine
2102  * to an external port on the NAT. The NAT should support either PCP, NAT-PMP or the
2103  * UPnP/IGD protocol for this API to create a successful mapping. Note that this API
2104  * currently supports IPv4 addresses/mappings only. If the NAT gateway supports PCP and
2105  * returns an IPv6 address (incorrectly, since this API specifically requests IPv4
2106  * addresses), the DNSServiceNATPortMappingReply callback will be invoked with errorCode
2107  * kDNSServiceErr_NATPortMappingUnsupported.
2108  *
2109  * The port mapping will be renewed indefinitely until the client process exits, or
2110  * explicitly terminates the port mapping request by calling DNSServiceRefDeallocate().
2111  * The client callback will be invoked, informing the client of the NAT gateway's
2112  * external IP address and the external port that has been allocated for this client.
2113  * The client should then record this external IP address and port using whatever
2114  * directory service mechanism it is using to enable peers to connect to it.
2115  * (Clients advertising services using Wide-Area DNS-SD DO NOT need to use this API
2116  * -- when a client calls DNSServiceRegister() NAT mappings are automatically created
2117  * and the external IP address and port for the service are recorded in the global DNS.
2118  * Only clients using some directory mechanism other than Wide-Area DNS-SD need to use
2119  * this API to explicitly map their own ports.)
2120  *
2121  * It's possible that the client callback could be called multiple times, for example
2122  * if the NAT gateway's IP address changes, or if a configuration change results in a
2123  * different external port being mapped for this client. Over the lifetime of any long-lived
2124  * port mapping, the client should be prepared to handle these notifications of changes
2125  * in the environment, and should update its recorded address and/or port as appropriate.
2126  *
2127  * NOTE: There are two unusual aspects of how the DNSServiceNATPortMappingCreate API works,
2128  * which were intentionally designed to help simplify client code:
2129  *
2130  *  1. It's not an error to request a NAT mapping when the machine is not behind a NAT gateway.
2131  *     In other NAT mapping APIs, if you request a NAT mapping and the machine is not behind a NAT
2132  *     gateway, then the API returns an error code -- it can't get you a NAT mapping if there's no
2133  *     NAT gateway. The DNSServiceNATPortMappingCreate API takes a different view. Working out
2134  *     whether or not you need a NAT mapping can be tricky and non-obvious, particularly on
2135  *     a machine with multiple active network interfaces. Rather than make every client recreate
2136  *     this logic for deciding whether a NAT mapping is required, the PortMapping API does that
2137  *     work for you. If the client calls the PortMapping API when the machine already has a
2138  *     routable public IP address, then instead of complaining about it and giving an error,
2139  *     the PortMapping API just invokes your callback, giving the machine's public address
2140  *     and your own port number. This means you don't need to write code to work out whether
2141  *     your client needs to call the PortMapping API -- just call it anyway, and if it wasn't
2142  *     necessary, no harm is done:
2143  *
2144  *     - If the machine already has a routable public IP address, then your callback
2145  *       will just be invoked giving your own address and port.
2146  *     - If a NAT mapping is required and obtained, then your callback will be invoked
2147  *       giving you the external address and port.
2148  *     - If a NAT mapping is required but not obtained from the local NAT gateway,
2149  *       or the machine has no network connectivity, then your callback will be
2150  *       invoked giving zero address and port.
2151  *
2152  *  2. In other NAT mapping APIs, if a laptop computer is put to sleep and woken up on a new
2153  *     network, it's the client's job to notice this, and work out whether a NAT mapping
2154  *     is required on the new network, and make a new NAT mapping request if necessary.
2155  *     The DNSServiceNATPortMappingCreate API does this for you, automatically.
2156  *     The client just needs to make one call to the PortMapping API, and its callback will
2157  *     be invoked any time the mapping state changes. This property complements point (1) above.
2158  *     If the client didn't make a NAT mapping request just because it determined that one was
2159  *     not required at that particular moment in time, the client would then have to monitor
2160  *     for network state changes to determine if a NAT port mapping later became necessary.
2161  *     By unconditionally making a NAT mapping request, even when a NAT mapping not to be
2162  *     necessary, the PortMapping API will then begin monitoring network state changes on behalf of
2163  *     the client, and if a NAT mapping later becomes necessary, it will automatically create a NAT
2164  *     mapping and inform the client with a new callback giving the new address and port information.
2165  *
2166  * DNSServiceNATPortMappingReply() parameters:
2167  *
2168  * sdRef:           The DNSServiceRef initialized by DNSServiceNATPortMappingCreate().
2169  *
2170  * flags:           Currently unused, reserved for future use.
2171  *
2172  * interfaceIndex:  The interface through which the NAT gateway is reached.
2173  *
2174  * errorCode:       Will be kDNSServiceErr_NoError on success.
2175  *                  Will be kDNSServiceErr_DoubleNAT when the NAT gateway is itself behind one or
2176  *                  more layers of NAT, in which case the other parameters have the defined values.
2177  *                  For other failures, will indicate the failure that occurred, and the other
2178  *                  parameters are undefined.
2179  *
2180  * externalAddress: Four byte IPv4 address in network byte order.
2181  *
2182  * protocol:        Will be kDNSServiceProtocol_UDP or kDNSServiceProtocol_TCP or both.
2183  *
2184  * internalPort:    The port on the local machine that was mapped.
2185  *
2186  * externalPort:    The actual external port in the NAT gateway that was mapped.
2187  *                  This is likely to be different than the requested external port.
2188  *
2189  * ttl:             The lifetime of the NAT port mapping created on the gateway.
2190  *                  This controls how quickly stale mappings will be garbage-collected
2191  *                  if the client machine crashes, suffers a power failure, is disconnected
2192  *                  from the network, or suffers some other unfortunate demise which
2193  *                  causes it to vanish without explicitly removing its NAT port mapping.
2194  *                  It's possible that the ttl value will differ from the requested ttl value.
2195  *
2196  * context:         The context pointer that was passed to the callout.
2197  *
2198  */
2199 
2200 typedef void (DNSSD_API *DNSServiceNATPortMappingReply)
2201 (
2202     DNSServiceRef sdRef,
2203     DNSServiceFlags flags,
2204     uint32_t interfaceIndex,
2205     DNSServiceErrorType errorCode,
2206     uint32_t externalAddress,                           /* four byte IPv4 address in network byte order */
2207     DNSServiceProtocol protocol,
2208     uint16_t internalPort,                              /* In network byte order */
2209     uint16_t externalPort,                              /* In network byte order and may be different than the requested port */
2210     uint32_t ttl,                                       /* may be different than the requested ttl */
2211     void                             *context
2212 );
2213 
2214 
2215 /* DNSServiceNATPortMappingCreate() Parameters:
2216  *
2217  * sdRef:           A pointer to an uninitialized DNSServiceRef
2218  *                  (or, if the kDNSServiceFlagsShareConnection flag is used,
2219  *                  a copy of the shared connection reference that is to be used).
2220  *                  If the call succeeds then it initializes (or updates) the DNSServiceRef,
2221  *                  returns kDNSServiceErr_NoError, and the NAT port mapping
2222  *                  will remain active indefinitely until the client terminates it
2223  *                  by passing this DNSServiceRef to DNSServiceRefDeallocate()
2224  *                  (or by closing the underlying shared connection, if used).
2225  *
2226  * flags:           Possible values are:
2227  *                  kDNSServiceFlagsShareConnection to use a shared connection.
2228  *
2229  * interfaceIndex:  The interface on which to create port mappings in a NAT gateway.
2230  *                  Passing 0 causes the port mapping request to be sent on the primary interface.
2231  *
2232  * protocol:        To request a port mapping, pass in kDNSServiceProtocol_UDP, or kDNSServiceProtocol_TCP,
2233  *                  or (kDNSServiceProtocol_UDP | kDNSServiceProtocol_TCP) to map both.
2234  *                  The local listening port number must also be specified in the internalPort parameter.
2235  *                  To just discover the NAT gateway's external IP address, pass zero for protocol,
2236  *                  internalPort, externalPort and ttl.
2237  *
2238  * internalPort:    The port number in network byte order on the local machine which is listening for packets.
2239  *
2240  * externalPort:    The requested external port in network byte order in the NAT gateway that you would
2241  *                  like to map to the internal port. Pass 0 if you don't care which external port is chosen for you.
2242  *
2243  * ttl:             The requested renewal period of the NAT port mapping, in seconds.
2244  *                  If the client machine crashes, suffers a power failure, is disconnected from
2245  *                  the network, or suffers some other unfortunate demise which causes it to vanish
2246  *                  unexpectedly without explicitly removing its NAT port mappings, then the NAT gateway
2247  *                  will garbage-collect old stale NAT port mappings when their lifetime expires.
2248  *                  Requesting a short TTL causes such orphaned mappings to be garbage-collected
2249  *                  more promptly, but consumes system resources and network bandwidth with
2250  *                  frequent renewal packets to keep the mapping from expiring.
2251  *                  Requesting a long TTL is more efficient on the network, but in the event of the
2252  *                  client vanishing, stale NAT port mappings will not be garbage-collected as quickly.
2253  *                  Most clients should pass 0 to use a system-wide default value.
2254  *
2255  * callBack:        The function to be called when the port mapping request succeeds or fails asynchronously.
2256  *
2257  * context:         An application context pointer which is passed to the callback function
2258  *                  (may be NULL).
2259  *
2260  * return value:    Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
2261  *                  errors are delivered to the callback), otherwise returns an error code indicating
2262  *                  the error that occurred.
2263  *
2264  *                  If you don't actually want a port mapped, and are just calling the API
2265  *                  because you want to find out the NAT's external IP address (e.g. for UI
2266  *                  display) then pass zero for protocol, internalPort, externalPort and ttl.
2267  */
2268 
2269 DNSSD_EXPORT
2270 DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
2271 (
2272     DNSServiceRef                    *sdRef,
2273     DNSServiceFlags flags,
2274     uint32_t interfaceIndex,
2275     DNSServiceProtocol protocol,                        /* TCP and/or UDP          */
2276     uint16_t internalPort,                              /* network byte order      */
2277     uint16_t externalPort,                              /* network byte order      */
2278     uint32_t ttl,                                       /* time to live in seconds */
2279     DNSServiceNATPortMappingReply callBack,
2280     void                             *context           /* may be NULL             */
2281 );
2282 
2283 
2284 /*********************************************************************************************
2285 *
2286 *  General Utility Functions
2287 *
2288 *********************************************************************************************/
2289 
2290 /* DNSServiceConstructFullName()
2291  *
2292  * Concatenate a three-part domain name (as returned by the above callbacks) into a
2293  * properly-escaped full domain name. Note that callbacks in the above functions ALREADY ESCAPE
2294  * strings where necessary.
2295  *
2296  * Parameters:
2297  *
2298  * fullName:        A pointer to a buffer that where the resulting full domain name is to be written.
2299  *                  The buffer must be kDNSServiceMaxDomainName (1009) bytes in length to
2300  *                  accommodate the longest legal domain name without buffer overrun.
2301  *
2302  * service:         The service name - any dots or backslashes must NOT be escaped.
2303  *                  May be NULL (to construct a PTR record name, e.g.
2304  *                  "_ftp._tcp.apple.com.").
2305  *
2306  * regtype:         The service type followed by the protocol, separated by a dot
2307  *                  (e.g. "_ftp._tcp").
2308  *
2309  * domain:          The domain name, e.g. "apple.com.". Literal dots or backslashes,
2310  *                  if any, must be escaped, e.g. "1st\. Floor.apple.com."
2311  *
2312  * return value:    Returns kDNSServiceErr_NoError (0) on success, kDNSServiceErr_BadParam on error.
2313  *
2314  */
2315 
2316 DNSSD_EXPORT
2317 DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
2318 (
2319     char                            * const fullName,
2320     const char                      * const service,      /* may be NULL */
2321     const char                      * const regtype,
2322     const char                      * const domain
2323 );
2324 
2325 
2326 /*********************************************************************************************
2327 *
2328 *   TXT Record Construction Functions
2329 *
2330 *********************************************************************************************/
2331 
2332 /*
2333  * A typical calling sequence for TXT record construction is something like:
2334  *
2335  * Client allocates storage for TXTRecord data (e.g. declare buffer on the stack)
2336  * TXTRecordCreate();
2337  * TXTRecordSetValue();
2338  * TXTRecordSetValue();
2339  * TXTRecordSetValue();
2340  * ...
2341  * DNSServiceRegister( ... TXTRecordGetLength(), TXTRecordGetBytesPtr() ... );
2342  * TXTRecordDeallocate();
2343  * Explicitly deallocate storage for TXTRecord data (if not allocated on the stack)
2344  */
2345 
2346 
2347 /* TXTRecordRef
2348  *
2349  * Opaque internal data type.
2350  * Note: Represents a DNS-SD TXT record.
2351  */
2352 
2353 typedef union _TXTRecordRef_t { char PrivateData[16]; char *ForceNaturalAlignment; } TXTRecordRef;
2354 
2355 
2356 /* TXTRecordCreate()
2357  *
2358  * Creates a new empty TXTRecordRef referencing the specified storage.
2359  *
2360  * If the buffer parameter is NULL, or the specified storage size is not
2361  * large enough to hold a key subsequently added using TXTRecordSetValue(),
2362  * then additional memory will be added as needed using malloc(). Note that
2363  * an existing TXT record buffer should not be passed to TXTRecordCreate
2364  * to create a copy of another TXT Record. The correct way to copy TXTRecordRef
2365  * is creating an empty TXTRecordRef with TXTRecordCreate() first, and using
2366  * TXTRecordSetValue to set the same value.
2367  *
2368  * On some platforms, when memory is low, malloc() may fail. In this
2369  * case, TXTRecordSetValue() will return kDNSServiceErr_NoMemory, and this
2370  * error condition will need to be handled as appropriate by the caller.
2371  *
2372  * You can avoid the need to handle this error condition if you ensure
2373  * that the storage you initially provide is large enough to hold all
2374  * the key/value pairs that are to be added to the record.
2375  * The caller can precompute the exact length required for all of the
2376  * key/value pairs to be added, or simply provide a fixed-sized buffer
2377  * known in advance to be large enough.
2378  * A no-value (key-only) key requires  (1 + key length) bytes.
2379  * A key with empty value requires     (1 + key length + 1) bytes.
2380  * A key with non-empty value requires (1 + key length + 1 + value length).
2381  * For most applications, DNS-SD TXT records are generally
2382  * less than 100 bytes, so in most cases a simple fixed-sized
2383  * 256-byte buffer will be more than sufficient.
2384  * Recommended size limits for DNS-SD TXT Records are discussed in RFC 6763
2385  * <https://tools.ietf.org/html/rfc6763#section-6.2>
2386  *
2387  * Note: When passing parameters to and from these TXT record APIs,
2388  * the key name does not include the '=' character. The '=' character
2389  * is the separator between the key and value in the on-the-wire
2390  * packet format; it is not part of either the key or the value.
2391  *
2392  * txtRecord:       A pointer to an uninitialized TXTRecordRef.
2393  *
2394  * bufferLen:       The size of the storage provided in the "buffer" parameter.
2395  *
2396  * buffer:          Optional caller-supplied storage used to hold the TXTRecord data.
2397  *                  This storage must remain valid for as long as
2398  *                  the TXTRecordRef.
2399  */
2400 
2401 DNSSD_EXPORT
2402 void DNSSD_API TXTRecordCreate
2403 (
2404     TXTRecordRef     *txtRecord,
2405     uint16_t bufferLen,
2406     void             *buffer
2407 );
2408 
2409 
2410 /* TXTRecordDeallocate()
2411  *
2412  * Releases any resources allocated in the course of preparing a TXT Record
2413  * using TXTRecordCreate()/TXTRecordSetValue()/TXTRecordRemoveValue().
2414  * Ownership of the buffer provided in TXTRecordCreate() returns to the client.
2415  *
2416  * txtRecord:           A TXTRecordRef initialized by calling TXTRecordCreate().
2417  *
2418  */
2419 
2420 DNSSD_EXPORT
2421 void DNSSD_API TXTRecordDeallocate
2422 (
2423     TXTRecordRef     *txtRecord
2424 );
2425 
2426 
2427 /* TXTRecordSetValue()
2428  *
2429  * Adds a key (optionally with value) to a TXTRecordRef. If the "key" already
2430  * exists in the TXTRecordRef, then the current value will be replaced with
2431  * the new value.
2432  * Keys may exist in four states with respect to a given TXT record:
2433  *  - Absent (key does not appear at all)
2434  *  - Present with no value ("key" appears alone)
2435  *  - Present with empty value ("key=" appears in TXT record)
2436  *  - Present with non-empty value ("key=value" appears in TXT record)
2437  * For more details refer to "Data Syntax for DNS-SD TXT Records" in RFC 6763
2438  * <https://tools.ietf.org/html/rfc6763#section-6>
2439  *
2440  * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
2441  *
2442  * key:             A null-terminated string which only contains printable ASCII
2443  *                  values (0x20-0x7E), excluding '=' (0x3D). Keys should be
2444  *                  9 characters or fewer (not counting the terminating null).
2445  *
2446  * valueSize:       The size of the value.
2447  *
2448  * value:           Any binary value. For values that represent
2449  *                  textual data, UTF-8 is STRONGLY recommended.
2450  *                  For values that represent textual data, valueSize
2451  *                  should NOT include the terminating null (if any)
2452  *                  at the end of the string.
2453  *                  If NULL, then "key" will be added with no value.
2454  *                  If non-NULL but valueSize is zero, then "key=" will be
2455  *                  added with empty value.
2456  *
2457  * return value:    Returns kDNSServiceErr_NoError on success.
2458  *                  Returns kDNSServiceErr_Invalid if the "key" string contains
2459  *                  illegal characters.
2460  *                  Returns kDNSServiceErr_NoMemory if adding this key would
2461  *                  exceed the available storage.
2462  */
2463 
2464 DNSSD_EXPORT
2465 DNSServiceErrorType DNSSD_API TXTRecordSetValue
2466 (
2467     TXTRecordRef     *txtRecord,
2468     const char       *key,
2469     uint8_t valueSize,                 /* may be zero */
2470     const void       *value            /* may be NULL */
2471 );
2472 
2473 
2474 /* TXTRecordRemoveValue()
2475  *
2476  * Removes a key from a TXTRecordRef. The "key" must be an
2477  * ASCII string which exists in the TXTRecordRef.
2478  *
2479  * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
2480  *
2481  * key:             A key name which exists in the TXTRecordRef.
2482  *
2483  * return value:    Returns kDNSServiceErr_NoError on success.
2484  *                  Returns kDNSServiceErr_NoSuchKey if the "key" does not
2485  *                  exist in the TXTRecordRef.
2486  */
2487 
2488 DNSSD_EXPORT
2489 DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
2490 (
2491     TXTRecordRef     *txtRecord,
2492     const char       *key
2493 );
2494 
2495 
2496 /* TXTRecordGetLength()
2497  *
2498  * Allows you to determine the length of the raw bytes within a TXTRecordRef.
2499  *
2500  * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
2501  *
2502  * return value:    Returns the size of the raw bytes inside a TXTRecordRef
2503  *                  which you can pass directly to DNSServiceRegister() or
2504  *                  to DNSServiceUpdateRecord().
2505  *                  Returns 0 if the TXTRecordRef is empty.
2506  */
2507 
2508 DNSSD_EXPORT
2509 uint16_t DNSSD_API TXTRecordGetLength
2510 (
2511     const TXTRecordRef *txtRecord
2512 );
2513 
2514 
2515 /* TXTRecordGetBytesPtr()
2516  *
2517  * Allows you to retrieve a pointer to the raw bytes within a TXTRecordRef.
2518  *
2519  * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
2520  *
2521  * return value:    Returns a pointer to the raw bytes inside the TXTRecordRef
2522  *                  which you can pass directly to DNSServiceRegister() or
2523  *                  to DNSServiceUpdateRecord().
2524  */
2525 
2526 DNSSD_EXPORT
2527 const void * DNSSD_API TXTRecordGetBytesPtr
2528 (
2529     const TXTRecordRef *txtRecord
2530 );
2531 
2532 
2533 /*********************************************************************************************
2534 *
2535 *   TXT Record Parsing Functions
2536 *
2537 *********************************************************************************************/
2538 
2539 /*
2540  * A typical calling sequence for TXT record parsing is something like:
2541  *
2542  * Receive TXT record data in DNSServiceResolve() callback
2543  * if (TXTRecordContainsKey(txtLen, txtRecord, "key")) then do something
2544  * val1ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key1", &len1);
2545  * val2ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key2", &len2);
2546  * ...
2547  * memcpy(myval1, val1ptr, len1);
2548  * memcpy(myval2, val2ptr, len2);
2549  * ...
2550  * return;
2551  *
2552  * If you wish to retain the values after return from the DNSServiceResolve()
2553  * callback, then you need to copy the data to your own storage using memcpy()
2554  * or similar, as shown in the example above.
2555  *
2556  * If for some reason you need to parse a TXT record you built yourself
2557  * using the TXT record construction functions above, then you can do
2558  * that using TXTRecordGetLength and TXTRecordGetBytesPtr calls:
2559  * TXTRecordGetValue(TXTRecordGetLength(x), TXTRecordGetBytesPtr(x), key, &len);
2560  *
2561  * Most applications only fetch keys they know about from a TXT record and
2562  * ignore the rest.
2563  * However, some debugging tools wish to fetch and display all keys.
2564  * To do that, use the TXTRecordGetCount() and TXTRecordGetItemAtIndex() calls.
2565  */
2566 
2567 /* TXTRecordContainsKey()
2568  *
2569  * Allows you to determine if a given TXT Record contains a specified key.
2570  *
2571  * txtLen:          The size of the received TXT Record.
2572  *
2573  * txtRecord:       Pointer to the received TXT Record bytes.
2574  *
2575  * key:             A null-terminated ASCII string containing the key name.
2576  *
2577  * return value:    Returns 1 if the TXT Record contains the specified key.
2578  *                  Otherwise, it returns 0.
2579  */
2580 
2581 DNSSD_EXPORT
2582 int DNSSD_API TXTRecordContainsKey
2583 (
2584     uint16_t txtLen,
2585     const void       *txtRecord,
2586     const char       *key
2587 );
2588 
2589 
2590 /* TXTRecordGetValuePtr()
2591  *
2592  * Allows you to retrieve the value for a given key from a TXT Record.
2593  *
2594  * txtLen:          The size of the received TXT Record
2595  *
2596  * txtRecord:       Pointer to the received TXT Record bytes.
2597  *
2598  * key:             A null-terminated ASCII string containing the key name.
2599  *
2600  * valueLen:        On output, will be set to the size of the "value" data.
2601  *
2602  * return value:    Returns NULL if the key does not exist in this TXT record,
2603  *                  or exists with no value (to differentiate between
2604  *                  these two cases use TXTRecordContainsKey()).
2605  *                  Returns pointer to location within TXT Record bytes
2606  *                  if the key exists with empty or non-empty value.
2607  *                  For empty value, valueLen will be zero.
2608  *                  For non-empty value, valueLen will be length of value data.
2609  */
2610 
2611 DNSSD_EXPORT
2612 const void * DNSSD_API TXTRecordGetValuePtr
2613 (
2614     uint16_t txtLen,
2615     const void       *txtRecord,
2616     const char       *key,
2617     uint8_t          *valueLen
2618 );
2619 
2620 
2621 /* TXTRecordGetCount()
2622  *
2623  * Returns the number of keys stored in the TXT Record. The count
2624  * can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
2625  *
2626  * txtLen:          The size of the received TXT Record.
2627  *
2628  * txtRecord:       Pointer to the received TXT Record bytes.
2629  *
2630  * return value:    Returns the total number of keys in the TXT Record.
2631  *
2632  */
2633 
2634 DNSSD_EXPORT
2635 uint16_t DNSSD_API TXTRecordGetCount
2636 (
2637     uint16_t txtLen,
2638     const void       *txtRecord
2639 );
2640 
2641 
2642 /* TXTRecordGetItemAtIndex()
2643  *
2644  * Allows you to retrieve a key name and value pointer, given an index into
2645  * a TXT Record. Legal index values range from zero to TXTRecordGetCount()-1.
2646  * It's also possible to iterate through keys in a TXT record by simply
2647  * calling TXTRecordGetItemAtIndex() repeatedly, beginning with index zero
2648  * and increasing until TXTRecordGetItemAtIndex() returns kDNSServiceErr_Invalid.
2649  *
2650  * On return:
2651  * For keys with no value, *value is set to NULL and *valueLen is zero.
2652  * For keys with empty value, *value is non-NULL and *valueLen is zero.
2653  * For keys with non-empty value, *value is non-NULL and *valueLen is non-zero.
2654  *
2655  * txtLen:          The size of the received TXT Record.
2656  *
2657  * txtRecord:       Pointer to the received TXT Record bytes.
2658  *
2659  * itemIndex:       An index into the TXT Record.
2660  *
2661  * keyBufLen:       The size of the string buffer being supplied.
2662  *
2663  * key:             A string buffer used to store the key name.
2664  *                  On return, the buffer contains a null-terminated C-string
2665  *                  giving the key name. DNS-SD TXT keys are usually
2666  *                  9 characters or fewer. To hold the maximum possible
2667  *                  key name, the buffer should be 256 bytes long.
2668  *
2669  * valueLen:        On output, will be set to the size of the "value" data.
2670  *
2671  * value:           On output, *value is set to point to location within TXT
2672  *                  Record bytes that holds the value data.
2673  *
2674  * return value:    Returns kDNSServiceErr_NoError on success.
2675  *                  Returns kDNSServiceErr_NoMemory if keyBufLen is too short.
2676  *                  Returns kDNSServiceErr_Invalid if index is greater than
2677  *                  TXTRecordGetCount()-1.
2678  */
2679 
2680 DNSSD_EXPORT
2681 DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
2682 (
2683     uint16_t txtLen,
2684     const void       *txtRecord,
2685     uint16_t itemIndex,
2686     uint16_t keyBufLen,
2687     char             *key,
2688     uint8_t          *valueLen,
2689     const void       **value
2690 );
2691 
2692 #if _DNS_SD_LIBDISPATCH
2693 /*
2694  * DNSServiceSetDispatchQueue
2695  *
2696  * Allows you to schedule a DNSServiceRef on a serial dispatch queue for receiving asynchronous
2697  * callbacks.  It's the clients responsibility to ensure that the provided dispatch queue is running.
2698  *
2699  * A typical application that uses CFRunLoopRun or dispatch_main on its main thread will
2700  * usually schedule DNSServiceRefs on its main queue (which is always a serial queue)
2701  * using "DNSServiceSetDispatchQueue(sdref, dispatch_get_main_queue());"
2702  *
2703  * If there is any error during the processing of events, the application callback will
2704  * be called with an error code. For shared connections, each subordinate DNSServiceRef
2705  * will get its own error callback. Currently these error callbacks only happen
2706  * if the daemon is manually terminated or crashes, and the error
2707  * code in this case is kDNSServiceErr_ServiceNotRunning. The application must call
2708  * DNSServiceRefDeallocate to free the DNSServiceRef when it gets such an error code.
2709  * These error callbacks are rare and should not normally happen on customer machines,
2710  * but application code should be written defensively to handle such error callbacks
2711  * gracefully if they occur.
2712  *
2713  * After using DNSServiceSetDispatchQueue on a DNSServiceRef, calling DNSServiceProcessResult
2714  * on the same DNSServiceRef will result in undefined behavior and should be avoided.
2715  *
2716  * Once the application successfully schedules a DNSServiceRef on a serial dispatch queue using
2717  * DNSServiceSetDispatchQueue, it cannot remove the DNSServiceRef from the dispatch queue, or use
2718  * DNSServiceSetDispatchQueue a second time to schedule the DNSServiceRef onto a different serial dispatch
2719  * queue. Once scheduled onto a dispatch queue a DNSServiceRef will deliver events to that queue until
2720  * the application no longer requires that operation and terminates it using DNSServiceRefDeallocate.
2721  * Note that the call to DNSServiceRefDeallocate() must be done on the same queue originally passed
2722  * as an argument to DNSServiceSetDispatchQueue().
2723  *
2724  * service:         DNSServiceRef that was allocated and returned to the application, when the
2725  *                  application calls one of the DNSService API.
2726  *
2727  * queue:           dispatch queue where the application callback will be scheduled
2728  *
2729  * return value:    Returns kDNSServiceErr_NoError on success.
2730  *                  Returns kDNSServiceErr_NoMemory if it cannot create a dispatch source
2731  *                  Returns kDNSServiceErr_BadParam if the service param is invalid or the
2732  *                  queue param is invalid
2733  */
2734 
2735 DNSSD_EXPORT
2736 DNSServiceErrorType DNSSD_API DNSServiceSetDispatchQueue
2737 (
2738     DNSServiceRef service,
2739     dispatch_queue_t queue
2740 );
2741 #endif //_DNS_SD_LIBDISPATCH
2742 
2743 #if !defined(_WIN32)
2744 typedef void (DNSSD_API *DNSServiceSleepKeepaliveReply)
2745 (
2746     DNSServiceRef sdRef,
2747     DNSServiceErrorType errorCode,
2748     void                                *context
2749 );
2750 DNSSD_EXPORT
2751 DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
2752 (
2753     DNSServiceRef                       *sdRef,
2754     DNSServiceFlags flags,
2755     int fd,
2756     unsigned int timeout,
2757     DNSServiceSleepKeepaliveReply callBack,
2758     void                                *context
2759 );
2760 #endif
2761 
2762 /* Some C compiler cleverness. We can make the compiler check certain things for us,
2763  * and report errors at compile-time if anything is wrong. The usual way to do this would
2764  * be to use a run-time "if" statement or the conventional run-time "assert" mechanism, but
2765  * then you don't find out what's wrong until you run the software. This way, if the assertion
2766  * condition is false, the array size is negative, and the complier complains immediately.
2767  */
2768 
2769 struct CompileTimeAssertionChecks_DNS_SD
2770 {
2771     char assert0[(sizeof(union _TXTRecordRef_t) == 16) ? 1 : -1];
2772 };
2773 
2774 #ifdef  __cplusplus
2775 }
2776 #endif
2777 
2778 #endif  /* _DNS_SD_H */
2779