Resolving DNS Hostnames
This article explains how to resolve a DNS hostname in a way that offers you maximum flexibility.
There are three primary APIs in OS X and iOS for resolving hostnames: NSHost (only in OS X), CFHost, and the POSIX resolver API.
NSHost—Although passing
NSHostis a common way to pass hostnames to other APIs, usingNSHostto resolve addresses yourself is generally discouraged because it is a synchronous API. Thus, using it on the main thread can cause serious performance degradation. Because this API is discouraged, its use is not described here.CFHost—The
CFHostAPI allows you to perform resolution asynchronously, and is the preferred way to resolve hostnames if you must resolve them yourself.POSIX—The POSIX layer provides several functions for resolving hostnames. These functions should be used only if you are writing portable code that must be shared with non-Apple platforms or if you are integrating your code with existing POSIX networking code.
Resolving Hostnames with CFHost
To resolve a host with CFHost:
Create a
CFHostRefobject by callingCFHostCreateWithName.Call
CFHostSetClientand provide the context object of your choice and a callback function that will be called when resolution completes.Call
CFHostScheduleWithRunLoopto schedule the resolver on your run loop.Call
CFHostStartInfoResolutionto tell the resolver to start resolving, passingkCFHostAddressesas the second parameter to indicate that you want it to return IP addresses.Wait for the resolver to call your callback. Within your callback, obtain the results by calling
CFHostGetAddressing. This function returns an array ofCFDataRefobjects, each of which contains a POSIXsockaddrstructure.
The process for reverse name resolution (translating an IP address into a hostname) is similar, except that you call CFHostCreateWithAddress to create the object, pass kCFHostNames to CFHostStartInfoResolution, and call CFHostGetNames to retrieve the results.
Resolving Hostnames with POSIX Calls
If you intend to use POSIX calls to resolve hostnames, be aware that these calls are synchronous and should not be used on the main thread in a GUI app. Instead, you should either create a separate POSIX thread or a GCD task and perform these calls within that context.
POSIX defines three functions in <netdb.h> for resolving hostnames:
Returns all the resolved addresses for a given hostname. This function is the preferred way to obtain address information at the POSIX level. You can find sample code in its man page (linked above).
Important: Some older DNS servers do not reply to IPv6 lookup requests with an error. The POSIX
getaddrinfofunction attempts to hide this misbehavior by canceling outstanding IPv6 queries shortly after receiving a successful IPv4 reply. If your app would benefit from continuing to receive IPv6 addresses until you connect successfully (rather than stopping as soon as you have an IPv4 address that might or might not work), then you should use an asynchronous API such asCFHost.Returns a single IPv4 address for a given hostname. This function is discouraged for new development because it is limited to IPv4 addresses.
Returns a single address for a given hostname in the specified address family (
AF_INET,AF_INET6, and so on).Although this function allows you to get around the IPv4 limitations of
gethostbyname, it still limits your ability to try multiple addresses at once and choose the fastest one. Thus, this function is primarily intended as a nearly drop-in replacement forgethostbynamein existing code. Thegetaddrinfois preferred for use in new code.
getaddrinfogethostbynamegethostbyname2For reverse name resolution (translating an IP address into a hostname), POSIX provides getnameinfo and gethostbyaddr. The getnameinfo function is preferred because it is more flexible.
To learn more about these functions, read their respective man pages, linked above.
Copyright © 2013 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2013-09-17