2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 Change History (most recent first):
28 Revision 1.7 2004/05/11 03:08:53 bradley
29 Updated TXT Record API based on latest proposal. This still includes dynamic TXT record building for
30 a final CVS snapshot for private libraries before this functionality is removed from the public API.
32 Revision 1.6 2004/05/06 18:42:58 ksekar
33 General dns_sd.h API cleanup, including the following radars:
34 <rdar://problem/3592068>: Remove flags with zero value
35 <rdar://problem/3479569>: Passing in NULL causes a crash.
37 Revision 1.5 2004/05/03 10:34:24 bradley
38 Implemented preliminary version of the TXTRecord API.
40 Revision 1.4 2004/04/15 01:00:05 bradley
41 Removed support for automatically querying for A/AAAA records when resolving names. Platforms
42 without .local name resolving support will need to manually query for A/AAAA records as needed.
44 Revision 1.3 2004/04/09 21:03:14 bradley
45 Changed port numbers to use network byte order for consistency with other platforms.
47 Revision 1.2 2004/04/08 09:43:42 bradley
48 Changed callback calling conventions to __stdcall so they can be used with C# delegates.
50 Revision 1.1 2004/01/30 02:45:21 bradley
51 High-level implementation of the DNS-SD API. Supports both "direct" (compiled-in mDNSCore) and "client"
52 (IPC<->service) usage. Conditionals can exclude either "direct" or "client" to reduce code size.
56 //---------------------------------------------------------------------------------------------------------------------------
59 @abstract DNS Service Discovery provides registration, domain and service discovery, and name resolving support.
63 High-level implementation of the DNS-SD API. This supports both "direct" (compiled-in mDNSCore) and "client" (IPC to
64 service) usage. Conditionals can exclude either "direct" or "client" to reduce code size.
70 #include "CommonServices.h"
77 #pragma mark == Configuration ==
80 //---------------------------------------------------------------------------------------------------------------------------
81 /*! @defined DNS_SD_DIRECT_ENABLED
83 @abstract Enables or disables DNS-SD direct.
86 #if( !defined( DNS_SD_DIRECT_ENABLED ) )
87 #define DNS_SD_DIRECT_ENABLED 1
90 //---------------------------------------------------------------------------------------------------------------------------
91 /*! @defined DNS_SD_CLIENT_ENABLED
93 @abstract Enables or disables DNS-SD client.
96 #if( !defined( DNS_SD_CLIENT_ENABLED ) )
97 #define DNS_SD_CLIENT_ENABLED 1
101 #pragma mark == Types ==
104 //---------------------------------------------------------------------------------------------------------------------------
105 /*! @typedef DNSServiceRef
107 @abstract Reference to a DNSService object.
111 Note: client is responsible for serializing access to these structures if they are shared between concurrent threads.
114 typedef struct _DNSServiceRef_t
* DNSServiceRef
;
116 //---------------------------------------------------------------------------------------------------------------------------
117 /*! @typedef DNSRecordRef
119 @abstract Reference to a DNSRecord object.
123 Note: client is responsible for serializing access to these structures if they are shared between concurrent threads.
126 typedef struct _DNSRecordRef_t
* DNSRecordRef
;
129 #pragma mark == Flags ==
132 //---------------------------------------------------------------------------------------------------------------------------
133 /*! @typedef DNSServiceFlags
135 @abstract General flags used in DNS-SD functions.
137 @constant kDNSServiceFlagsNone
138 No flags (makes it clearer to use this symbolic constant rather than using a 0).
140 @constant kDNSServiceFlagsMoreComing
141 MoreComing indicates to a callback that at least one more result is queued and will be delivered
142 following immediately after this one. Applications should not update their UI to display browse
143 results when the MoreComing flag is set, because this would result in a great deal of ugly
144 flickering on the screen. Applications should instead wait until until MoreComing is not set
145 (i.e. "Finished", for now), and then update their UI. When MoreComing is not set (i.e.
146 "Finished") that doesn't mean there will be no more answers EVER, just that there are no more
147 answers immediately available right now at this instant. If more answers become available in
148 the future they will be delivered as usual.
150 @constant kDNSServiceFlagsAdd
151 Service or domain has been added during browsing/querying or domain enumeration.
153 @constant kDNSServiceFlagsDefault
154 Default domain has been added during domain enumeration.
156 @constant kDNSServiceFlagsNoAutoRename
157 Auto renaming should not be performed. Only valid if a name is explicitly specified when
158 registering a service (i.e. the default name is not used).
160 @constant kDNSServiceFlagsShared
161 Shared flag for registering individual records on a connected DNSServiceRef. Indicates that there
162 may be multiple records with this name on the network (e.g. PTR records).
164 @constant kDNSServiceFlagsUnique
165 Shared flag for registering individual records on a connected DNSServiceRef. Indicates that the
166 record's name is to be unique on the network (e.g. SRV records).
168 @constant kDNSServiceFlagsBrowseDomains
169 Enumerates domains recommended for browsing.
171 @constant kDNSServiceFlagsRegistrationDomains
172 Enumerates domains recommended for registration.
175 typedef uint32_t DNSServiceFlags
;
178 kDNSServiceFlagsNone
= 0,
180 kDNSServiceFlagsMoreComing
= ( 1 << 0 ),
182 kDNSServiceFlagsAdd
= ( 1 << 1 ),
183 kDNSServiceFlagsDefault
= ( 1 << 2 ),
185 kDNSServiceFlagsNoAutoRename
= ( 1 << 3 ),
187 kDNSServiceFlagsShared
= ( 1 << 4 ),
188 kDNSServiceFlagsUnique
= ( 1 << 5 ),
190 kDNSServiceFlagsBrowseDomains
= ( 1 << 6 ),
191 kDNSServiceFlagsRegistrationDomains
= ( 1 << 7 )
194 //---------------------------------------------------------------------------------------------------------------------------
195 /*! @enum DNSServiceInitializeFlags
197 @abstract Flags used with DNSServiceInitialize.
199 @constant kDNSServiceInitializeFlagsAdvertise
200 Indicates that interfaces should be advertised on the network. Software that only performs searches
201 do not need to set this flag.
203 @constant kDNSServiceInitializeFlagsNoServerCheck
204 No check for a valid server should be performed. Only applicable if client support is enabled.
207 typedef uint32_t DNSServiceInitializeFlags
;
209 #define kDNSServiceInitializeFlagsNone 0
210 #define kDNSServiceInitializeFlagsAdvertise ( 1 << 0 )
211 #define kDNSServiceInitializeFlagsNoServerCheck ( 1 << 1 )
213 //---------------------------------------------------------------------------------------------------------------------------
214 /*! @defined kDNSServiceMaxDomainName
216 @abstract Maximum length, in bytes, of a domain name represented as an escaped C-String
219 #define kDNSServiceMaxDomainName 1005
221 //---------------------------------------------------------------------------------------------------------------------------
222 /*! @defined kDNSServiceInterfaceIndexAny
224 @abstract Interface index to indicate any interface.
227 #define kDNSServiceInterfaceIndexAny 0
229 //---------------------------------------------------------------------------------------------------------------------------
230 /*! @defined kDNSServiceInterfaceIndexAny
232 @abstract Use the local interface only.
235 #define kDNSServiceInterfaceIndexLocalOnly ( (uint32_t) ~0 )
238 #pragma mark == Errors ==
241 //---------------------------------------------------------------------------------------------------------------------------
242 /*! @typedef DNSServiceErrorType
244 @abstract Possible error code values.
247 typedef int32_t DNSServiceErrorType
;
250 // Error codes are in the range FFFE FF00 (-65792) to FFFE FFFF (-65537)
252 kDNSServiceErr_NoError
= 0,
253 kDNSServiceErr_Unknown
= -65537, // 0xFFFE FFFF (first error code)
254 kDNSServiceErr_NoSuchName
= -65538,
255 kDNSServiceErr_NoMemory
= -65539,
256 kDNSServiceErr_BadParam
= -65540,
257 kDNSServiceErr_BadReference
= -65541,
258 kDNSServiceErr_BadState
= -65542,
259 kDNSServiceErr_BadFlags
= -65543,
260 kDNSServiceErr_Unsupported
= -65544,
261 kDNSServiceErr_NotInitialized
= -65545,
262 kDNSServiceErr_NoCache
= -65546,
263 kDNSServiceErr_AlreadyRegistered
= -65547,
264 kDNSServiceErr_NameConflict
= -65548,
265 kDNSServiceErr_Invalid
= -65549,
266 kDNSServiceErr_Incompatible
= -65551,
267 kDNSServiceErr_BadInterfaceIndex
= -65552,
268 kDNSServiceErr_Refused
= -65553,
269 kDNSServiceErr_NoSuchRecord
= -65554,
270 kDNSServiceErr_NoAuth
= -65555,
271 kDNSServiceErr_NoSuchKey
= -65556,
272 kDNSServiceErr_NoValue
= -65557,
273 kDNSServiceErr_BufferTooSmall
= -65558,
275 // TCP Connection Status
277 kDNSServiceErr_ConnectionPending
= -65570,
278 kDNSServiceErr_ConnectionFailed
= -65571,
279 kDNSServiceErr_ConnectionEstablished
= -65572,
283 kDNSServiceErr_GrowCache
= -65790,
284 kDNSServiceErr_ConfigChanged
= -65791,
285 kDNSServiceErr_MemFree
= -65792 // 0xFFFE FF00 (last error code)
288 //---------------------------------------------------------------------------------------------------------------------------
289 /*! @var gDNSSDServer
291 @abstract Global controlling the server to communicate with. Set to NULL for local operation.
294 extern const char * gDNSSDServer
;
297 #pragma mark == DNS Classes ==
300 //---------------------------------------------------------------------------------------------------------------------------
301 /*! @enum DNSServiceDNSClass
306 typedef enum // From RFC 1035
308 kDNSServiceDNSClass_IN
= 1, // Internet
309 kDNSServiceDNSClass_CS
= 2, // CSNET
310 kDNSServiceDNSClass_CH
= 3, // CHAOS
311 kDNSServiceDNSClass_HS
= 4, // Hesiod
312 kDNSServiceDNSClass_NONE
= 254, // Used in DNS UPDATE [RFC 2136]
314 kDNSServiceDNSClass_Mask
= 0x7FFF, // Multicast DNS uses the bottom 15 bits to identify the record class...
315 kDNSServiceDNSClass_UniqueRRSet
= 0x8000, // ... and the top bit indicates that all other cached records are now invalid
317 kDNSServiceDNSQClass_ANY
= 255, // Not a DNS class, but a DNS query class, meaning "all classes"
318 kDNSServiceDNSQClass_UnicastResponse
= 0x8000 // Top bit set in a question means "unicast response acceptable"
320 } DNSServiceDNSClass
;
323 #pragma mark == DNS Types ==
326 //---------------------------------------------------------------------------------------------------------------------------
327 /*! @enum DNSServiceDNSType
332 typedef enum // From RFC 1035
334 kDNSServiceDNSType_A
= 1, // Address
335 kDNSServiceDNSType_NS
= 2, // Name Server
336 kDNSServiceDNSType_MD
= 3, // Mail Destination
337 kDNSServiceDNSType_MF
= 4, // Mail Forwarder
338 kDNSServiceDNSType_CNAME
= 5, // Canonical Name
339 kDNSServiceDNSType_SOA
= 6, // Start of Authority
340 kDNSServiceDNSType_MB
= 7, // Mailbox
341 kDNSServiceDNSType_MG
= 8, // Mail Group
342 kDNSServiceDNSType_MR
= 9, // Mail Rename
343 kDNSServiceDNSType_NULL
= 10, // NULL RR
344 kDNSServiceDNSType_WKS
= 11, // Well-known-service
345 kDNSServiceDNSType_PTR
= 12, // Domain name pointer
346 kDNSServiceDNSType_HINFO
= 13, // Host information
347 kDNSServiceDNSType_MINFO
= 14, // Mailbox information
348 kDNSServiceDNSType_MX
= 15, // Mail Exchanger
349 kDNSServiceDNSType_TXT
= 16, // Arbitrary text string
350 kDNSServiceDNSType_AAAA
= 28, // IPv6 address
351 kDNSServiceDNSType_SRV
= 33, // Service record
352 kDNSServiceDNSTypeQType_ANY
= 255 // Not a DNS type, but a DNS query type, meaning "all types"
357 #pragma mark == General ==
360 //---------------------------------------------------------------------------------------------------------------------------
361 /*! @function DNSServiceInitialize
363 @abstract Initializes DNS-SD.
365 @param inFlags Flags to control the initialization process (only applicable for DNS-SD direct).
366 @param inCacheEntryCount Size of the cache (only applicable for DNS-SD direct).
369 DNSServiceErrorType
DNSServiceInitialize( DNSServiceInitializeFlags inFlags
, int inCacheEntryCount
);
371 //---------------------------------------------------------------------------------------------------------------------------
372 /*! @function DNSServiceFinalize
374 @abstract Finalizes DNS-SD.
377 void DNSServiceFinalize( void );
379 //---------------------------------------------------------------------------------------------------------------------------
380 /*! @function DNSServiceCheckVersion
382 @abstract Performs a version check. Mainly only needed when client-mode is enabled to verify the server is compatible.
385 DNSServiceErrorType
DNSServiceCheckVersion( void );
388 #pragma mark == Properties ==
391 //---------------------------------------------------------------------------------------------------------------------------
392 /*! @typedef DNSPropertyCode
394 @abstract Identifies a property.
397 typedef uint32_t DNSPropertyCode
;
399 #define kDNSPropertyCodeVersion 0x76657273 // 'vers'
401 // Format: <w:serverCurrentVersion> <w:serverOldestClientVersion> <w:serverOldestServerVersion>
403 //---------------------------------------------------------------------------------------------------------------------------
404 /*! @struct DNSPropertyData
406 @abstract Data for a property.
409 typedef struct DNSPropertyData DNSPropertyData
;
410 struct DNSPropertyData
412 DNSPropertyCode code
;
418 uint32_t clientCurrentVersion
;
419 uint32_t clientOldestServerVersion
;
420 uint32_t serverCurrentVersion
;
421 uint32_t serverOldestClientVersion
;
428 //---------------------------------------------------------------------------------------------------------------------------
429 /*! @function DNSServiceCopyProperty
431 @abstract Copies a property into a newly allocated buffer.
433 @param inCode Property to copy.
434 @param outData Receives the copied property data. Must be release with DNSServiceReleaseProperty.
437 DNSServiceErrorType
DNSServiceCopyProperty( DNSPropertyCode inCode
, DNSPropertyData
*outData
);
439 //---------------------------------------------------------------------------------------------------------------------------
440 /*! @function DNSServiceReleaseProperty
442 @abstract Releases a property copied with a successful call to DNSServiceCopyProperty.
445 DNSServiceErrorType
DNSServiceReleaseProperty( DNSPropertyData
*inData
);
448 #pragma mark == Unix Domain Socket Access ==
451 //---------------------------------------------------------------------------------------------------------------------------
452 /*! @function DNSServiceRefSockFD
454 @param inRef A DNSServiceRef initialized by any of the DNSService calls.
456 @result The DNSServiceRef's underlying socket descriptor, or -1 on error.
460 Access underlying Unix domain socket for an initialized DNSServiceRef. The DNS Service Discovery implmementation uses
461 this socket to communicate between the client and the mDNSResponder daemon. The application MUST NOT directly read
462 from or write to this socket. Access to the socket is provided so that it can be used as a run loop source, or in a
463 select() loop: when data is available for reading on the socket, DNSServiceProcessResult() should be called, which will
464 extract the daemon's reply from the socket, and pass it to the appropriate application callback. By using a run loop
465 or select(), results from the daemon can be processed asynchronously. Without using these constructs,
466 DNSServiceProcessResult() will block until the response from the daemon arrives. The client is responsible for ensuring
467 that the data on the socket is processed in a timely fashion - the daemon may terminate its connection with a client
468 that does not clear its socket buffer.
471 int DNSServiceRefSockFD( DNSServiceRef inRef
);
473 //---------------------------------------------------------------------------------------------------------------------------
474 /*! @function DNSServiceProcessResult
476 @param inRef A DNSServiceRef initialized by any of the DNSService calls that take a callback parameter.
478 @result Returns kDNSServiceErr_NoError on success, otherwise returns an error code indicating the specific failure
483 Read a reply from the daemon, calling the appropriate application callback. This call will block until the daemon's
484 response is received. Use DNSServiceRefSockFD() in conjunction with a run loop or select() to determine the presence
485 of a response from the server before calling this function to process the reply without blocking. Call this function
486 at any point if it is acceptable to block until the daemon's response arrives. Note that the client is responsible
487 for ensuring that DNSServiceProcessResult() is called whenever there is a reply from the daemon - the daemon may
488 terminate its connection with a client that does not process the daemon's responses.
491 DNSServiceErrorType
DNSServiceProcessResult( DNSServiceRef inRef
);
493 //---------------------------------------------------------------------------------------------------------------------------
494 /*! @function DNSServiceRefDeallocate
496 @param inRef A DNSServiceRef initialized by any of the DNSService calls.
500 Terminate a connection with the daemon and free memory associated with the DNSServiceRef. Any services or records
501 registered with this DNSServiceRef will be deregistered. Any Browse, Resolve, or Query operations called with this
502 reference will be terminated.
504 Note: If the reference's underlying socket is used in a run loop or select() call, it should be removed BEFORE
505 DNSServiceRefDeallocate() is called, as this function closes the reference's socket.
507 Note: If the reference was initialized with DNSServiceCreateConnection(), any DNSRecordRefs created via this reference
508 will be invalidated by this call - the resource records are deregistered, and their DNSRecordRefs may not be used in
509 subsequent functions. Similarly, if the reference was initialized with DNSServiceRegister, and an extra resource record
510 was added to the service via DNSServiceAddRecord(), the DNSRecordRef created by the Add() call is invalidated when this
511 function is called - the DNSRecordRef may not be used in subsequent functions.
513 Note: This call is to be used only with the DNSServiceRef defined by this API. It is not compatible with
514 dns_service_discovery_ref objects defined in the legacy Mach-based DNSServiceDiscovery.h API.
517 void DNSServiceRefDeallocate( DNSServiceRef inRef
);
520 #pragma mark == Domain Enumeration ==
523 //---------------------------------------------------------------------------------------------------------------------------
524 /*! @typedef DNSServiceDomainEnumReply
526 @abstract Callback function for DNSServiceEnumerateDomains.
529 The DNSServiceRef initialized by DNSServiceEnumerateDomains().
537 @param inInterfaceIndex
538 Specifies the interface on which the domain exists. (The index for a given interface is determined
539 via the if_nametoindex() family of calls).
542 Will be kDNSServiceErr_NoError (0) on success, otherwise indicates the failure that occurred (other
543 parameters are undefined if errorCode is nonzero).
546 The name of the domain.
549 The context pointer passed to DNSServiceEnumerateDomains.
553 ( CALLBACK_COMPAT
*DNSServiceDomainEnumReply
)(
555 DNSServiceFlags inFlags
,
556 uint32_t inInterfaceIndex
,
557 DNSServiceErrorType inErrorCode
,
558 const char * inDomain
,
561 //---------------------------------------------------------------------------------------------------------------------------
562 /*! @function DNSServiceEnumerateDomains
564 @abstract Asynchronously enumerate domains available for browsing and registration.
567 A pointer to an uninitialized DNSServiceRef. May be passed to DNSServiceRefDeallocate() to cancel the
572 64 (BrowseDomains) to enumerate domains recommended for browsing.
573 128 (RegistrationDomains) to enumerate domains recommended for registration.
575 @param inInterfaceIndex
576 If non-zero, specifies the interface on which to look for domains (the index for a given interface is
577 determined via the if_nametoindex() family of calls). Most applications will pass 0 to enumerate
578 domains on all interfaces.
581 The function to be called when a domain is found or the call asynchronously fails.
584 An application context pointer which is passed to the callback function (may be NULL).
586 @result Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous errors are delivered to the
587 callback), otherwise returns an error code indicating the error that occurred (the callback is not invoked
588 and the DNSServiceRef is not initialized).
592 Currently, the only domain returned is "local.", but other domains will be returned in future.
594 The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains are to be found.
598 DNSServiceEnumerateDomains(
599 DNSServiceRef
* outRef
,
600 const DNSServiceFlags inFlags
,
601 const uint32_t inInterfaceIndex
,
602 const DNSServiceDomainEnumReply inCallBack
,
603 void * inContext
); // may be NULL
606 #pragma mark == Service Registration ==
609 //---------------------------------------------------------------------------------------------------------------------------
610 /*! @typedef DNSServiceRegisterReply
612 @abstract Callback function for DNSServiceRegister.
615 The DNSServiceRef initialized by DNSServiceRegister().
618 Currently unused, reserved for future use.
621 Will be kDNSServiceErr_NoError on success, otherwise will indicate the failure that occurred
622 (including name conflicts, if the kDNSServiceFlagsNoAutoRenameOnConflict flag was passed to the
623 callout). Other parameters are undefined if errorCode is nonzero.
626 The service name registered (if the application did not specify a name in DNSServiceRegister(), this
627 indicates what name was automatically chosen).
630 The type of service registered, as it was passed to the callout.
633 The domain on which the service was registered (if the application did not specify a domain in
634 DNSServiceRegister(), this indicates the default domain on which the service was registered).
637 The context pointer that was passed to the callout.
641 ( CALLBACK_COMPAT
*DNSServiceRegisterReply
)(
643 DNSServiceFlags inFlags
,
644 DNSServiceErrorType inErrorCode
,
647 const char * inDomain
,
650 //---------------------------------------------------------------------------------------------------------------------------
651 /*! @function DNSServiceRegister
653 @abstract Register a service that is discovered via Browse() and Resolve() calls.
656 A pointer to an uninitialized DNSServiceRef. If this call succeeds, the reference may be passed to
657 DNSServiceRefDeallocate() to deregister the service.
659 @param inInterfaceIndex
660 If non-zero, specifies the interface on which to register the service (the index for a given interface
661 is determined via the if_nametoindex() family of calls). Most applications will pass 0 to register on
662 all available interfaces. Pass -1 to register a service only on the local machine (service will not be
663 visible to remote hosts).
666 Indicates the renaming behavior on name conflict (most applications will pass 0). See flag definitions
670 If non-NULL, specifies the service name to be registered. Most applications will not specify a name, in
671 which case the computer name is used (this name is communicated to the client via the callback).
674 The service type followed by the protocol, separated by a dot (e.g. "_ftp._tcp"). The transport protocol
675 must be "_tcp" or "_udp".
678 If non-NULL, specifies the domain on which to advertise the service. Most applications will not specify
679 a domain, instead automatically registering in the default domain(s).
682 If non-NULL, specifies the SRV target host name. Most applications will not specify a host, instead
683 automatically using the machine's default host name(s). Note that specifying a non-NULL host does NOT
684 create an address record for that host - the application is responsible for ensuring that the appropriate
685 address record exists, or creating it via DNSServiceRegisterRecord().
688 The port on which the service accepts connections in network byte order. Pass 0 for a "placeholder"
689 service (i.e. a service that will not be discovered by browsing, but will cause a name conflict if
690 another client tries to register that same name). Most clients will not use placeholder services.
693 The length of the txtRecord, in bytes. Must be zero if the txtRecord is NULL.
696 The txt record rdata. May be NULL. Note that a non-NULL txtRecord MUST be a properly formatted DNS TXT
697 record, i.e. <length byte> <data> <length byte> <data> ...
700 The function to be called when the registration completes or asynchronously fails. The client MAY pass
701 NULL for the callback - The client will NOT be notified of the default values picked on its behalf, and
702 the client will NOT be notified of any asynchronous errors (e.g. out of memory errors, etc). that may
703 prevent the registration of the service. The client may NOT pass the NoAutoRename flag if the callback
704 is NULL. The client may still deregister the service at any time via DNSServiceRefDeallocate().
707 An application context pointer which is passed to the callback function (may be NULL).
709 @result Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous errors are delivered to the
710 callback), otherwise returns an error code indicating the error that occurred (the callback is never invoked
711 and the DNSServiceRef is not initialized).
716 DNSServiceRef
* outRef
,
717 DNSServiceFlags inFlags
,
718 uint32_t inInterfaceIndex
,
719 const char * inName
, // may be NULL
721 const char * inDomain
, // may be NULL
722 const char * inHost
, // may be NULL
725 const void * inTXT
, // may be NULL
726 DNSServiceRegisterReply inCallBack
, // may be NULL
727 void * inContext
); // may be NULL
729 //---------------------------------------------------------------------------------------------------------------------------
730 /*! @function DNSServiceAddRecord
732 @abstract Add a record to a registered service.
735 A DNSServiceRef initialized by DNSServiceRegister().
738 A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this call, this ref may be
739 passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord(). If the above DNSServiceRef is passed
740 to DNSServiceRefDeallocate(), RecordRef is also invalidated and may not be used further.
743 Currently ignored, reserved for future use.
746 The type of the record (e.g. TXT, SRV, etc), as defined in nameser.h.
749 The length, in bytes, of the rdata.
752 The raw rdata to be contained in the added resource record.
755 The time to live of the resource record, in seconds.
757 @result Returns kDNSServiceErr_NoError on success, otherwise returns an error code indicating the error that
758 occurred (the RecordRef is not initialized).
762 The name of the record will be the same as the registered service's name. The record can later be updated or
763 deregistered by passing the RecordRef initialized by this function to DNSServiceUpdateRecord() or
764 DNSServiceRemoveRecord().
770 DNSRecordRef
* inRecordRef
,
771 DNSServiceFlags inFlags
,
773 uint16_t inRDataSize
,
774 const void * inRData
,
777 //---------------------------------------------------------------------------------------------------------------------------
778 /*! @function DNSServiceUpdateRecord
780 @abstract Update a registered resource record.
783 A DNSServiceRef that was initialized by DNSServiceRegister() or DNSServiceCreateConnection().
786 A DNSRecordRef initialized by DNSServiceAddRecord, or NULL to update the service's primary txt record.
789 Currently ignored, reserved for future use.
792 The length, in bytes, of the new rdata.
795 The new rdata to be contained in the updated resource record.
798 The time to live of the updated resource record, in seconds.
800 @result Returns kDNSServiceErr_NoError on success, otherwise returns an error code indicating the error that occurred.
804 The record must either be:
805 - The primary txt record of a service registered via DNSServiceRegister()
806 - A record added to a registered service via DNSServiceAddRecord()
807 - An individual record registered by DNSServiceRegisterRecord()
811 DNSServiceUpdateRecord(
813 DNSRecordRef inRecordRef
, // may be NULL
814 DNSServiceFlags inFlags
,
815 uint16_t inRDataSize
,
816 const void * inRData
,
819 //---------------------------------------------------------------------------------------------------------------------------
820 /*! @function DNSServiceRemoveRecord
822 @abstract Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
823 an record registered individually via DNSServiceRegisterRecord().
826 A DNSServiceRef that was initialized by DNSServiceRegister() or DNSServiceCreateConnection().
829 A DNSRecordRef initialized by a successful call to DNSServiceAddRecord() or DNSServiceRegisterRecord().
832 Currently ignored, reserved for future use.
834 @result Returns kDNSServiceErr_NoError on success, otherwise returns an error code indicating the error that occurred.
838 DNSServiceRemoveRecord(
840 DNSRecordRef inRecordRef
,
841 DNSServiceFlags inFlags
);
844 #pragma mark == Service Discovery ==
847 //---------------------------------------------------------------------------------------------------------------------------
848 /*! @typedef DNSServiceBrowseReply
850 @abstract Callback function for DNSServiceBrowse.
853 The DNSServiceRef initialized by DNSServiceBrowse().
856 Possible values are MoreComing and Add/Remove. See flag definitions for details.
858 @param inInterfaceIndex
859 The interface on which the service is advertised. This index should be passed to DNSServiceResolve()
860 when resolving the service.
863 Will be kDNSServiceErr_NoError (0) on success, otherwise will indicate the failure that occurred.
864 Other parameters are undefined if the errorCode is nonzero.
867 The service name discovered.
870 The service type, as passed in to DNSServiceBrowse().
873 The domain on which the service was discovered (if the application did not specify a domain in
874 DNSServicBrowse(), this indicates the domain on which the service was discovered).
877 The context pointer that was passed to the callout.
881 ( CALLBACK_COMPAT
*DNSServiceBrowseReply
)(
883 DNSServiceFlags inFlags
,
884 uint32_t inInterfaceIndex
,
885 DNSServiceErrorType inErrorCode
,
888 const char * inDomain
,
891 //---------------------------------------------------------------------------------------------------------------------------
892 /*! @function DNSServiceBrowse
894 @abstract Browse for instances of a service.
897 A pointer to an uninitialized DNSServiceRef. May be passed to DNSServiceRefDeallocate() to terminate
901 Currently ignored, reserved for future use.
903 @param inInterfaceIndex
904 If non-zero, specifies the interface on which to browse for services (the index for a given interface
905 is determined via the if_nametoindex() family of calls). Most applications will pass 0 to browse on all
906 available interfaces. Pass -1 to only browse for services provided on the local host.
909 The service type being browsed for followed by the protocol, separated by a dot (e.g. "_ftp._tcp").
910 The transport protocol must be "_tcp" or "_udp".
913 If non-NULL, specifies the domain on which to browse for services. Most applications will not specify a
914 domain, instead browsing on the default domain(s).
917 The function to be called when an instance of the service being browsed for is found, or if the call
918 asynchronously fails.
921 An application context pointer which is passed to the callback function (may be NULL).
923 @result Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous errors are delivered to the
924 callback), otherwise returns an error code indicating the error that occurred (the callback is not invoked
925 and the DNSServiceRef is not initialized).
930 DNSServiceRef
* outRef
,
931 DNSServiceFlags inFlags
,
932 uint32_t inInterfaceIndex
,
934 const char * inDomain
, // may be NULL
935 DNSServiceBrowseReply inCallBack
,
936 void * inContext
); // may be NULL
938 //---------------------------------------------------------------------------------------------------------------------------
939 /*! @typedef DNSServiceResolveReply
941 @abstract Callback function for DNSServiceResolve.
944 The DNSServiceRef initialized by DNSServiceResolve().
947 Currently unused, reserved for future use.
949 @param inInterfaceIndex
950 The interface on which the service was resolved.
953 Will be kDNSServiceErr_NoError (0) on success, otherwise will indicate the failure that occurred.
954 Other parameters are undefined if the errorCode is nonzero.
957 The full service domain name, in the form <servicename>.<protocol>.<domain>. (Any literal dots (".")
958 are escaped with a backslash ("\."), and literal backslashes are escaped with a second backslash ("\\"),
959 e.g. a web server named "Dr. Pepper" would have the fullname "Dr\.\032Pepper._http._tcp.local.").
960 This is the appropriate format to pass to standard system DNS APIs such as res_query(), or to the
961 special-purpose functions included in this API that take fullname parameters.
964 The target hostname of the machine providing the service. This name can be passed to functions like
965 gethostbyname() to identify the host's IP address.
968 The port number on which connections are accepted for this service in network byte order.
971 The length of the txt record, in bytes.
974 The service's primary txt record, in standard txt record format.
977 The context pointer that was passed to the callout.
981 ( CALLBACK_COMPAT
*DNSServiceResolveReply
)(
983 DNSServiceFlags inFlags
,
984 uint32_t inInterfaceIndex
,
985 DNSServiceErrorType inErrorCode
,
986 const char * inFullName
,
987 const char * inHostName
,
993 //---------------------------------------------------------------------------------------------------------------------------
994 /*! @function DNSServiceResolve
996 @abstract Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and txt record.
999 A pointer to an uninitialized DNSServiceRef. May be passed to DNSServiceRefDeallocate() to terminate
1003 Currently unused, reserved for future use.
1005 @param inInterfaceIndex
1006 The interface on which to resolve the service. The client should pass the interface on which the
1007 servicename was discovered, i.e. the inInterfaceIndex passed to the DNSServiceBrowseReply callback, or 0
1008 to resolve the named service on all available interfaces.
1011 The service name to be resolved.
1014 The service type being resolved followed by the protocol, separated by a dot (e.g. "_ftp._tcp"). The
1015 transport protocol must be "_tcp" or "_udp".
1018 The domain on which the service is registered, i.e. the domain passed to the DNSServiceBrowseReply
1022 The function to be called when a result is found, or if the call asynchronously fails.
1025 An application context pointer which is passed to the callback function (may be NULL).
1027 @result Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous errors are delivered to the
1028 callback), otherwise returns an error code indicating the error that occurred (the callback is never
1029 invoked and the DNSServiceRef is not initialized). The context pointer that was passed to the callout.
1033 Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and txt record.
1035 Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use DNSServiceQueryRecord()
1036 instead, as it is more efficient for this task.
1038 Note: When the desired results have been returned, the client MUST terminate the resolve by calling
1039 DNSServiceRefDeallocate().
1041 Note: DNSServiceResolve() behaves correctly for typical services that have a single SRV record and a single TXT record
1042 (the TXT record may be empty). To resolve non-standard services with multiple SRV or TXT records,
1043 DNSServiceQueryRecord() should be used.
1048 DNSServiceRef
* outRef
,
1049 DNSServiceFlags inFlags
,
1050 uint32_t inInterfaceIndex
,
1051 const char * inName
,
1052 const char * inType
,
1053 const char * inDomain
,
1054 DNSServiceResolveReply inCallBack
,
1055 void * inContext
); // may be NULL
1058 #pragma mark == Special Purpose ==
1061 //---------------------------------------------------------------------------------------------------------------------------
1062 /*! @function DNSServiceConstructFullName
1064 @abstract Concatenate a three-part domain name (as returned by the above callbacks) into a properly-escaped full
1065 domain name. Note that callbacks in the above functions ALREADY ESCAPE strings where necessary.
1068 A pointer to a buffer that where the resulting full domain name is to be written. The buffer must be
1069 kDNSServiceDiscoveryMaxDomainName (1005) bytes in length to accommodate the longest legal domain name
1070 without buffer overrun.
1073 The service name - any dots or slashes must NOT be escaped. May be NULL (to construct a PTR record
1074 name, e.g. "_ftp._tcp.apple.com").
1077 The service type followed by the protocol, separated by a dot (e.g. "_ftp._tcp").
1080 The domain name, e.g. "apple.com". Any literal dots or backslashes must be escaped.
1082 @result Returns 0 on success, -1 on error.
1086 DNS Naming Conventions:
1088 The following functions refer to resource records by their full domain name, unlike the above
1089 functions which divide the name into servicename/regtype/domain fields. In the above functions,
1090 a dot (".") is considered to be a literal dot in the servicename field (e.g. "Dr. Pepper") and
1091 a label separator in the regtype ("_ftp._tcp") or domain ("apple.com") fields. Literal dots in
1092 the domain field would be escaped with a backslash, and literal backslashes would be escaped with
1093 a second backslash (this is generally not an issue, as domain names on the Internet today almost
1094 never use characters other than letters, digits, or hyphens, and the dots are label separators).
1095 Furthermore, this is transparent to the caller, so long as the fields are passed between functions
1096 without manipulation. However, the following, special-purpose calls use a single, full domain name.
1097 As such, all dots are considered to be label separators, unless escaped, and all backslashes are
1098 considered to be escape characters, unless preceded by a second backslash. For example, the name
1099 "Dr. Smith \ Dr. Johnson" could be passed literally as a service name parameter in the above calls,
1100 but in the special purpose call, the dots and backslash would have to be escaped
1101 (e.g. "Dr\. Smith \\ Dr\. Johnson._ftp._tcp.apple.com" for an ftp service on the apple.com domain).
1105 DNSServiceConstructFullName(
1107 const char * inName
, // may be NULL
1108 const char * inType
,
1109 const char * inDomain
);
1111 //---------------------------------------------------------------------------------------------------------------------------
1112 /*! @function DNSServiceCreateConnection
1114 @abstract Create a connection to the daemon allowing efficient registration of multiple individual records.
1117 A pointer to an uninitialized DNSServiceRef. Deallocating the reference (via DNSServiceRefDeallocate())
1118 severs the connection and deregisters all records registered on this connection.
1120 @result Returns kDNSServiceErr_NoError on success, otherwise returns an error code indicating the specific failure
1121 that occurred (in which case the DNSServiceRef is not initialized).
1125 DNSServiceErrorType
DNSServiceCreateConnection( DNSServiceRef
*outRef
);
1127 //---------------------------------------------------------------------------------------------------------------------------
1128 /*! @typedef DNSServiceRegisterRecordReply
1130 @abstract Callback function for DNSServiceRegisterRecord.
1133 The connected DNSServiceRef initialized by DNSServiceCreateConnection().
1136 The DNSRecordRef initialized by DNSServiceRegisterRecord(). If the above DNSServiceRef is passed to
1137 DNSServiceRefDeallocate(), this DNSRecordRef is invalidated, and may not be used further.
1140 Currently unused, reserved for future use.
1143 Will be kDNSServiceErr_NoError on success, otherwise will indicate the failure that occurred (including
1144 name conflicts). Other parameters are undefined if errorCode is nonzero.
1147 The context pointer that was passed to the callout.
1151 ( CALLBACK_COMPAT
*DNSServiceRegisterRecordReply
)(
1152 DNSServiceRef inRef
,
1153 DNSRecordRef inRecordRef
,
1154 DNSServiceFlags inFlags
,
1155 DNSServiceErrorType inErrorCode
,
1158 //---------------------------------------------------------------------------------------------------------------------------
1159 /*! @function DNSServiceRegisterRecord
1161 @abstract Register an individual resource record on a connected DNSServiceRef.
1164 A DNSServiceRef initialized by DNSServiceCreateConnection().
1167 A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this call, this ref may be
1168 passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord(). (To deregister ALL records registered
1169 on a single connected DNSServiceRef and deallocate each of their corresponding DNSServiceRecordRefs,
1170 call DNSServiceRefDealloocate()).
1173 Possible values are Shared/Unique (see flag type definitions for details).
1175 @param inInterfaceIndex
1176 If non-zero, specifies the interface on which to register the record (the index for a given interface
1177 is determined via the if_nametoindex() family of calls). Passing 0 causes the record to be registered
1178 on all interfaces. Passing -1 causes the record to only be visible on the local host.
1181 The full domain name of the resource record.
1184 The numerical type of the resource record (e.g. PTR, SRV, etc), as defined in nameser.h.
1187 The class of the resource record, as defined in nameser.h (usually 1 for the Internet class).
1190 Length, in bytes, of the rdata.
1193 A pointer to the raw rdata, as it is to appear in the DNS record.
1196 The time to live of the resource record, in seconds.
1199 The function to be called when a result is found, or if the call asynchronously fails (e.g. because
1200 of a name conflict).
1203 An application context pointer which is passed to the callback function (may be NULL).
1205 @result Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous errors are delivered to the
1206 callback), otherwise returns an error code indicating the error that occurred (the callback is never
1207 invoked and the DNSRecordRef is not initialized).
1211 Note that name conflicts occurring for records registered via this call must be handled by the client in the callback.
1215 DNSServiceRegisterRecord(
1216 DNSServiceRef inRef
,
1217 DNSRecordRef
* inRecordRef
,
1218 DNSServiceFlags inFlags
,
1219 uint32_t inInterfaceIndex
,
1220 const char * inFullName
,
1223 uint16_t inRDataSize
,
1224 const void * inRData
,
1226 DNSServiceRegisterRecordReply inCallBack
,
1229 //---------------------------------------------------------------------------------------------------------------------------
1230 /*! @typedef DNSServiceQueryRecordReply
1232 @abstract Callback function for DNSServiceQueryRecord.
1235 The DNSServiceRef initialized by DNSServiceQueryRecord().
1238 Possible values are Finished/MoreComing and Add/Remove. The Remove flag is set for PTR records with
1241 @param inInterfaceIndex
1242 The interface on which the query was resolved (the index for a given interface is determined via the
1243 if_nametoindex() family of calls).
1246 Will be kDNSServiceErr_NoError on success, otherwise will indicate the failure that occurred. Other
1247 parameters are undefined if errorCode is nonzero.
1250 The resource record's full domain name.
1253 The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
1256 The class of the resource record, as defined in nameser.h (usually 1).
1259 The length, in bytes, of the resource record rdata.
1262 The raw rdata of the resource record.
1265 The resource record's time to live, in seconds.
1268 The context pointer that was passed to the callout.
1272 ( CALLBACK_COMPAT
*DNSServiceQueryRecordReply
)(
1273 DNSServiceRef inRef
,
1274 DNSServiceFlags inFlags
,
1275 uint32_t inInterfaceIndex
,
1276 DNSServiceErrorType inErrorCode
,
1277 const char * inFullName
,
1280 uint16_t inRDataSize
,
1281 const void * inRData
,
1285 //---------------------------------------------------------------------------------------------------------------------------
1286 /*! @function DNSServiceQueryRecord
1288 @abstract Query for an arbitrary DNS record.
1291 A pointer to an uninitialized DNSServiceRef.
1294 Currently unused, reserved for future use.
1296 @param inInterfaceIndex
1297 If non-zero, specifies the interface on which to issue the query (the index for a given interface is
1298 determined via the if_nametoindex() family of calls). Passing 0 causes the name to be queried for on all
1299 interfaces. Passing -1 causes the name to be queried for only on the local host.
1302 The full domain name of the resource record to be queried for.
1305 The numerical type of the resource record to be queried for (e.g. PTR, SRV, etc) as defined in nameser.h.
1308 The class of the resource record, as defined in nameser.h (usually 1 for the Internet class).
1311 The function to be called when a result is found, or if the call asynchronously fails.
1314 An application context pointer which is passed to the callback function (may be NULL).
1316 @result Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous errors are delivered to the
1317 callback), otherwise returns an error code indicating the error that occurred (the callback is never
1318 invoked and the DNSServiceRef is not initialized).
1322 Note that name conflicts occurring for records registered via this call must be handled by the client in the callback.
1326 DNSServiceQueryRecord(
1327 DNSServiceRef
* outRef
,
1328 DNSServiceFlags inFlags
,
1329 uint32_t inInterfaceIndex
,
1330 const char * inName
,
1333 DNSServiceQueryRecordReply inCallBack
,
1334 void * inContext
); // may be NULL
1336 //---------------------------------------------------------------------------------------------------------------------------
1337 /*! @function DNSServiceReconfirmRecord
1339 @abstract Instruct the daemon to verify the validity of a resource record that appears to be out of date (e.g.
1340 because tcp connection to a service's target failed). Causes the record to be flushed from the daemon's
1341 cache (as well as all other daemons' caches on the network) if the record is determined to be invalid.
1344 Currently unused, reserved for future use.
1347 The resource record's full domain name.
1350 The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
1353 The class of the resource record, as defined in nameser.h (usually 1).
1356 The length, in bytes, of the resource record rdata.
1359 The raw rdata of the resource record.
1363 DNSServiceReconfirmRecord(
1364 DNSServiceFlags inFlags
,
1365 uint32_t inInterfaceIndex
,
1366 const char * inName
,
1369 uint16_t inRDataSize
,
1370 const void * inRData
);
1373 #pragma mark == TXT Record Building ==
1376 //---------------------------------------------------------------------------------------------------------------------------
1377 /*! @typedef TXTRecordRef
1379 @abstract Reference to a TXTRecord object representing a DNS-SD TXT record.
1383 Note: client is responsible for serializing access to these structures if they are shared between concurrent threads.
1386 typedef struct _TXTRecordRef_t
* TXTRecordRef
;
1388 //---------------------------------------------------------------------------------------------------------------------------
1389 /*! @function TXTRecordCreate
1391 @abstract Creates an empty TXTRecordRef.
1394 A pointer to an uninitialized TXTRecordRef. Filled in on success.
1396 @result Returns kDNSServiceErr_NoError on success.
1397 Returns kDNSServiceErr_BadParam if the reference pointer is NULL.
1398 Returns kDNSServiceErr_NoMemory if there is not enough memory to create the TXTRecord.
1402 Once you've created a TXTRecordRef, you can pass it to TXTRecordSetValue and other functions to add "key=value"
1403 pairs to it. Finally, you can extract the raw bytes again to pass to DNSServiceRegister() or DNSServiceUpdateRecord().
1405 A typical calling sequence for TXT record construction is something like:
1408 TXTRecordSetValue();
1409 TXTRecordSetValue();
1410 TXTRecordSetValue();
1412 DNSServiceRegister( ... TXTRecordGetLength(), TXTRecordGetBytesPtr() ... );
1413 TXTRecordDeallocate();
1416 DNSServiceErrorType
TXTRecordCreate( TXTRecordRef
*outRef
);
1418 //---------------------------------------------------------------------------------------------------------------------------
1419 /*! @function TXTRecordDeallocate
1421 @abstract Releases the memory associated with a TXTRecordRef.
1424 A TXTRecordRef initialized by calling TXTRecordCreate.
1427 void TXTRecordDeallocate( TXTRecordRef inRef
);
1429 //---------------------------------------------------------------------------------------------------------------------------
1430 /*! @function TXTRecordSetValue
1432 @abstract Adds a key (optionally with a value) to a TXTRecordRef.
1435 A TXTRecordRef initialized by TXTRecordCreate.
1438 Null-terminated key of the value to add. Must be at least 1 character and consist of only printable
1439 US-ASCII characters (0x20-0x7E), excluding '=' (0x3D). Should be 14 characters or less (not counting
1440 the terminating null). Keys are case insensitive (i.e. key "test" replaces key "TEST").
1443 Pointer to value to add. For values that represent textual data, UTF-8 is STRONGLY recommended.
1444 If NULL, then the key will be added with no value.
1445 If non-NULL but valueSize is zero, then "key=" will be added with an empty value.
1448 Number of bytes in the value. Must be 0 if inValue is NULL.
1450 @result Returns kDNSServiceErr_NoError on success.
1451 Returns kDNSServiceErr_BadParam if the parameters are illegal or not supported.
1452 Returns kDNSServiceErr_Invalid if the key string contains illegal characters.
1453 Returns kDNSServiceErr_NoMemory if there is not enough memory to set the value.
1457 If the key is already present in the TXTRecordRef, then the current value will be replaced with the new value.
1458 Keys may be in four states with respect to a given TXT record:
1460 - Absent (key does not appear at all).
1461 - Present with no value ("key" appears alone).
1462 - Present with empty value ("key=" appears in the TXT record).
1463 - Present with non-empty value ("key=value" appears in the TXT record).
1465 For more details refer to "Data Syntax for DNS-SD TXT Records" in
1466 <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
1473 uint8_t inValueSize
, // may be zero
1474 const void * inValue
); // may be NULL
1476 //---------------------------------------------------------------------------------------------------------------------------
1477 /*! @function TXTRecordRemoveValue
1479 @abstract Removes a key from a TXTRecordRef.
1482 A TXTRecordRef initialized by TXTRecordCreate.
1485 Null-terminated key to remove. Note: keys are case insensitive.
1487 @result Returns kDNSServiceErr_NoError on success.
1488 Returns kDNSServiceErr_NoSuchKey if the key is not present in the TXTRecordRef.
1489 Returns kDNSServiceErr_BadParam if the parameters are illegal or not supported.
1492 DNSServiceErrorType
TXTRecordRemoveValue( TXTRecordRef inRef
, const char *inKey
);
1494 //---------------------------------------------------------------------------------------------------------------------------
1495 /*! @function TXTRecordGetLength
1497 @abstract Returns the number of raw bytes inside a TXTRecordRef.
1500 A TXTRecordRef initialized by TXTRecordCreate.
1502 @result Returns the number of raw bytes inside a TXTRecordRef which you can pass directly to DNSServiceRegister()
1503 or to DNSServiceUpdateRecord(). Returns 0 if the TXTRecordRef is empty.
1507 The length may become invalid if you subsequently make changes to the TXTRecordRef by calling TXTRecordSetValue()
1508 or TXTRecordRemoveValue().
1511 uint16_t TXTRecordGetLength( TXTRecordRef inRef
);
1513 //---------------------------------------------------------------------------------------------------------------------------
1514 /*! @function TXTRecordGetBytesPtr
1516 @abstract Returns a pointer to the raw bytes inside the TXTRecordRef.
1519 A TXTRecordRef initialized by TXTRecordCreate.
1521 @result Returns a pointer to the raw bytes inside the TXTRecordRef which you can pass directly to
1522 DNSServiceRegister() or to DNSServiceUpdateRecord(). Returns NULL if the TXTRecordRef is empty.
1526 The pointer may become invalid if you subsequently make changes to the TXTRecordRef by calling TXTRecordSetValue()
1527 or TXTRecordRemoveValue().
1530 const void * TXTRecordGetBytesPtr( TXTRecordRef inRef
);
1533 #pragma mark == TXT Record Parsing ==
1536 /*---------------------------------------------------------------------------------------------------------------------------
1537 A typical calling sequence for TXT record parsing is something like:
1538 Receive TXT record data in the DNSServiceResolve() callback then:
1540 cosnt void * value1Ptr;
1543 err = TXTRecordGetValuePtr( txtSize, txtRecord, "key1", &value1Ptr, &value1Size );
1544 if( err == kDNSServiceErr_NoError )
1546 // "key1" found. Do work with "value1Ptr" data if needed.
1551 If you wish to retain the values after returning from the DNSServiceResolve() callback, then you need to copy the data
1552 to your own storage using memcpy() or something similar so it does not go out of scope until you're done with it.
1554 If for some reason you need to parse a TXT record you built yourself using the TXT record construction functions above,
1555 then you can do that using TXTRecordGetLength and TXTRecordGetBytesPtr functions:
1557 TXTRecordGetValue( TXTRecordGetLength( x ), TXTRecordGetBytesPtr( x ), "key1", &value1Ptr, &value1Size );
1559 Most applications only fetch keys they know about from a TXT record and ignore the rest.
1560 However, some debugging tools wish to fetch and display all keys. To do that, use the TXTRecordGetCount() and
1561 TXTRecordGetItemAtIndex() functions.
1564 //---------------------------------------------------------------------------------------------------------------------------
1565 /*! @function TXTRecordGetValuePtr
1567 @abstract Allows you to retrieve the value for a given key from a TXT Record.
1570 Number of bytes in the TXT record.
1573 Pointer to the raw TXT record bytes.
1576 A null-terminated key to search for. Note: keys are case insensitive.
1579 Pointer to be filled in with a pointer to the value within the TXT record bytes.
1580 Resulting pointer will be NULL if the key is present, but has no value.
1581 Resulting pointer will be non-NULL and size zero if the key is present, but has an empty value.
1582 Resulting pointer will be non-NULL and size non-zero if key is present and has a non-empty value.
1583 May be NULL if only interested in the value size or if the key is present.
1586 Pointer to receive the size of the value.
1587 Size will be 0 if there is no value or the value is empty.
1588 May be NULL if not interested in getting the size.
1590 @result Returns kDNSServiceErr_NoError if a key with the specified name is found.
1591 Returns kDNSServiceErr_NoSuchKey if the key does not exist in the TXTRecordRef.
1592 Returns kDNSServiceErr_BadParam if the parameters are illegal or not supported.
1593 Returns kDNSServiceErr_Invalid if the TXT record is malformed.
1597 The pointer may become invalid if you subsequently make changes to the TXT record by calling TXTRecordSetValue()
1598 or TXTRecordRemoveValue().
1602 TXTRecordGetValuePtr(
1604 const void * inTXTBytes
,
1606 const void ** outValue
, // may be NULL
1607 uint8_t * outValueSize
); // may be NULL
1609 //---------------------------------------------------------------------------------------------------------------------------
1610 /*! @function TXTRecordGetCount
1612 @abstract Returns the total number of keys in the TXT Record.
1615 Number of bytes in the TXT record.
1618 Pointer to the raw TXT record bytes.
1620 @result Returns the total number of keys in the TXT Record.
1624 The count can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
1625 The count may become invalid if you subsequently make changes to the TXT record by calling TXTRecordSetValue()
1626 or TXTRecordRemoveValue().
1629 uint16_t TXTRecordGetCount( uint16_t inTXTSize
, const void *inTXTBytes
);
1631 //---------------------------------------------------------------------------------------------------------------------------
1632 /*! @function TXTRecordGetItemAtIndex
1634 @abstract Allows you to retrieve a key name, given an index into a TXT Record.
1637 Number of bytes in the TXT record.
1640 Pointer to the raw TXT record bytes.
1643 Index of item to get. The index is 0-based (0 is the first item).
1644 Legal index values range from 0 to TXTRecordGetCount() - 1.
1647 A string buffer used to store the null-terminated key name. The buffer must be at least 256 bytes
1648 in order to hold the maximum possible key name.
1649 May be NULL if not interested in the key name.
1652 Pointer to be filled in with a pointer to the value within the TXT record bytes.
1653 Resulting pointer will be NULL if the key is present, but has no value.
1654 Resulting pointer will be non-NULL and size zero if the key is present, but has an empty value.
1655 Resulting pointer will be non-NULL and size non-zero if key is present and has a non-empty value.
1656 May be NULL if only interested in the value size or if the key is present.
1659 Pointer to receive the size of the value.
1660 Size will be 0 if there is no value or the value is empty.
1661 May be NULL if not interested in getting the size.
1663 @result Returns kDNSServiceErr_NoError if a key with the specified name is found.
1664 Returns kDNSServiceErr_Invalid if the index is greater than TXTRecordGetCount() - 1 or the TXT record is malformed.
1665 Returns kDNSServiceErr_BadParam if the parameters are illegal or not supported.
1669 It also possible to iterate through keys in a TXT record by simply calling TXTRecordGetItemAtIndex() repeatedly,
1670 beginning with index zero and increasing until TXTRecordGetItemAtIndex() returns an non-zero error code.
1672 The pointer may become invalid if you subsequently make changes to the TXTRecordRef by calling TXTRecordSetValue()
1673 or TXTRecordRemoveValue().
1677 TXTRecordGetItemAtIndex(
1679 const void * inTXTBytes
,
1681 char * inKeyBuffer
, // may be NULL
1682 const void ** outValue
, // may be NULL
1683 uint8_t * outValueSize
); // may be NULL