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