CFHostStartInfoResolution resovled result is 0.0.0.0

When my iPhone 6(iOS 12.2(16E227)) uses the network that is shared by my iMac, the following method testResolution print: ipAddress: 0.0.0.0

If not use the network shared by iMac, the following method can resolve domain successfully.

- (void)testResolution
{
    NSString *hostName = @"www.apple.com";

    CFHostRef host = CFHostCreateWithName(kCFAllocatorDefault, (__bridge CFStringRef)hostName);
    CFStreamError error;
    CFHostStartInfoResolution(host, kCFHostAddresses, &error);
   
    if (0 == error.error)
    {
        CFArrayRef addressArray = CFHostGetAddressing(host, NULL);
        if (addressArray && CFArrayGetCount(addressArray) > 0)
        {
            NSArray *sockaddrArray = (__bridge NSArray *)addressArray;
            for (NSData *sockaddrData in sockaddrArray)
            {
                struct sockaddr_in *sa_in = (struct sockaddr_in *)[sockaddrData bytes];
                const char *ipAddress = inet_ntoa(sa_in->sin_addr);
                printf("ipAddress: %s\n", ipAddress);
            }
        }
    }
   
    CFRelease(host);
}

Accepted Reply

Why are you using

CFHost
?

Most of our TCP APIs support connect-by-name semantics, so you don’t need a separate DNS resolution step. Moreover, Apple strongly encourages folks to use connect-by-name, because it gives the networking stack the information it needs to connect in all circumstances. So if you’re calling

CFHost
in preparation to, say, making an outgoing TCP connection, you should skip this step entirely and just pass this DNS name to a connect-by-name API.

ps The reason why you’re going is failing is that you’re interpreting the results from

CFHost
as an array of IPv4 addresses, whereas in reality it’s an array of IP addresses, which may be either IPv4 or IPv6. This is one of the common pitfalls that our connect-by-name APIs will handle for you.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Why are you using

CFHost
?

Most of our TCP APIs support connect-by-name semantics, so you don’t need a separate DNS resolution step. Moreover, Apple strongly encourages folks to use connect-by-name, because it gives the networking stack the information it needs to connect in all circumstances. So if you’re calling

CFHost
in preparation to, say, making an outgoing TCP connection, you should skip this step entirely and just pass this DNS name to a connect-by-name API.

ps The reason why you’re going is failing is that you’re interpreting the results from

CFHost
as an array of IPv4 addresses, whereas in reality it’s an array of IP addresses, which may be either IPv4 or IPv6. This is one of the common pitfalls that our connect-by-name APIs will handle for you.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Wow! You are right.

The reason of 0.0.0.0 is the resolved result is IPv6 addresses, because the shared network I created is NAT 64 network.

The reason I use CFHost is some addresses resolved from our own domain name are invalid.

I need to resolve our own domain first, then walk through the resolved addresses looking for one that I can work with.

I need to resolve our own domain first, then walk through the resolved addresses looking for one that I can work with.

Wow, that’s wacky. My recommendation is that you fix this on the server side. Having a DNS name map to multiple hosts is fine, but all of those hosts are meant to be equivalent. Having the same name map to non-equivalent hosts is asking for trouble.

Manually selecting the target IP address will fix your immediate problem but that just raises other problems. For example:

  • Dealing with IPv6 addresses in a DNS64/NAT64 environment

  • Deciding which interface to use for your connection — Imagine what happens if both Wi-Fi and WWAN are behind DNS64/NAT64.

  • Deciding between the various candidate IP addresses

  • Handling VPN On Demand

Apple’s connect-by-name APIs take care of all this mess for you.

Still, you’ll need a temporary workaround pending a server-side fix, and

CFHost
is a reasonable API to use. For a concrete example of how to use it properly, see CFHostSample.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank your recommendation, I will take it seriously. And thank your sample code, too.