Resolving the Current Address of a Service
This article describes how to use DNSServiceResolve to get information about a service based on its name, type, and domain.
Using DNSServiceResolve
Once you have the name, registration type, and domain of a service, you can get information about the service, such as the interface(s) on which the service is registered, the full domain name of the service, name of the host that provides the service, and the content of the service’s primary TXT record, by calling DNSServiceResolve.
To resolve a service name to its hostname and port, call DNSServiceResolve. The parameters for making this call consist of the following:
An uninitialized service discovery reference
The index of the interface on which you want to resolve the service; pass the value that was passed to your callback function for
DNSServiceBrowse, or0to resolve on all available interfacesThe service name to be resolved; pass a value that was passed to your callback function for
DNSServiceBrowseThe registration type of the service to be resolved; pass the value that was passed to your callback function for
DNSServiceBrowseThe domain in which the service is registered; pass the value that was passed to your callback function for
DNSServiceBrowseThe callback function that is to be called to provide information on the success or failure of the resolution
A user-defined context value that will be passed to the callback function when it is called, or
NULL
If the resolution can be started, DNSServiceResolve initializes the service discovery reference and creates a socket that is used to communicate with the mDNSResponder daemon. Use the service discovery reference to call DNSServiceRefSockFD and get the socket descriptor for the socket.
Setting Up a Callback Function
If DNSServiceResolve returns error-free, you need to have mDNSResponder resolve the service discovery reference and run a callback function when it has received a response. There are two techniques to set up the callback function: asynchronously and synchronously.
To get a response from mDNSResponder asynchronously, set up a run or a select loop using the socket descriptor. The loop will be notified whenever a response from the mDNSResponder daemon becomes available. When the loop indicates that a response is available, call DNSServiceProcessResult and pass to it the service discovery reference initialized by DNSServiceResolve. DNSServiceProcessResult will call the callback function associated with the service discovery reference. The mDNSResponder daemon will provide a response for each service that it resolves on a per-interface basis.
If you want to run the callback function synchronously instead of setting up a run loop or a select loop, you can call DNSServiceResolve and immediately call DNSServiceProcessResult. The DNSServiceProcessResult function will block until the mDNSResponder daemon has a response, at which time the callback specified when DNSServiceResolve was called will be invoked. This entire process should probably be run within a loop of its own for each service you wish to resolve.
In addition to the service discovery reference and flags that are not currently used, your callback will be called with the following parameters:
The interface index on which the service was resolved; use the
if_nametoindexfamily of calls to relate the index to an interface nameAn error code that indicates whether the resolution was successful; if the resolution was successful, the remaining parameters contain valid data
The full domain name of the service, suitable for passing to special purpose functions that take a full domain name as a parameter
The hostname of the machine that provides the service, suitable for passing to
gethostbynameorDNSServiceQueryRecordto get the host’s IP addressThe port number in network byte order on which the service accepts connections
The length of the TXT record for the service
The primary TXT record for the service in standard TXT record format (that is, a length byte followed by data, followed by a length byte, followed by data, and so on)
The user-defined context information that was passed to
DNSServiceResolve
Your run loop or select loop will be notified for each interface on which the service is resolved and for each TXT record associated with the service.
When the desired results have been obtained, you must terminate the resolution. Remove the socket descriptor from the run loop or the select loop and call DNSServiceRefDeallocate, passing to it the service discovery reference that was initialized when DNSServiceResolve was called. The service discovery reference is invalidated, and memory associated with the reference is deallocated. The socket that underlies the connection with the mDNSResponder daemon is closed, thereby terminating your application’s connection with the daemon.
Copyright © 2013 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2013-08-08