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:

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:

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.