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
NSHost
is a common way to pass hostnames to other APIs, usingNSHost
to 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
CFHost
API 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
CFHostRef
object by callingCFHostCreateWithName
.Call
CFHostSetClient
and provide the context object of your choice and a callback function that will be called when resolution completes.Call
CFHostScheduleWithRunLoop
to schedule the resolver on your run loop.Call
CFHostStartInfoResolution
to tell the resolver to start resolving, passingkCFHostAddresses
as 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 ofCFDataRef
objects, each of which contains a POSIXsockaddr
structure.
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
getaddrinfo
function 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 forgethostbyname
in existing code. Thegetaddrinfo
is preferred for use in new code.
getaddrinfo
gethostbyname
gethostbyname2
For 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