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