DNSServiceProcessResult() is a synchronous call that blocks, so I thought "Hey, I'll use GCD to address that problem". What I came up after some experimentation was:
static void callBack(
DNSServiceRef sdRef,
...
{
NSLog(@"Callback!");
if(theErrorCode == kDNSServiceErr_NoError) {
// if no error,stop updating
DNSServiceRefDeallocate(sdRef);
}
}
dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
DNSServiceRef sdRef;
DNSServiceQueryRecord(&sdRef, 0, 0, [domain UTF8String], kDNSServiceType_MX, kDNSServiceClass_IN, callBack, NULL);
DNSServiceErrorType theErrorCode = DNSServiceProcessResult(sdRef);
if(theErrorCode != kDNSServiceErr_NoError) {
// there was an error so the callback never did the dealloc
DNSServiceRefDeallocate(sdRef);
}
});
The above code appears to work fine for the "no-error" case. When I give it a made up name, like "foo.foobar", it hangs for a long time - like forever!
So then I thought "I'll just verify the domain first" - so I used gethostbyname2() to do it. But then I found that my ISP (and probably a lot of others) use this DNS hijacking service called "BAREFOOT" in the EU. When a DNS entry isn't found (for real) you get told that BAREFOOT is the address and you get routed there! Yikes!
So - how do I do this? Verify that a domain really exists, then see if it has a MX record, and on a background thread?