So as you’ve no doubt noticed if you’ve tried to port conventional DNS resolving code like ares to the iPhone, your desktop Mac OS code to get DNS servers like this
SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL};
SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("init_by_defaults_systemconfiguration"), NULL, &context);
CFStringRef key = CFSTR("State:/Network/Global/DNS");
CFDictionaryRef dnsDict = SCDynamicStoreCopyValue(store, key);
CFArrayRef addresses = (CFArrayRef) CFDictionaryGetValue(dnsDict, kSCPropNetDNSServerAddresses);
doesn’t work so hot, as SCDynamicStore APIs aren’t available. What to do? What to do? Well, when we first encountered this problem, after asking around the developer forums, and StackOverflow, and macnetworkprog, we didn’t get any good advice besides “rewrite using Bonjour”, essentially. Luckily, in our particular application we could put in hardcoded server addresses and pretend the problem didn’t exist.
But even more luckily, there are people out there better informed and/or more tenacious than trolls; so here is a solution using resolv.h that some bright spark who stumbled across our begging on the dev forums came up with, which you could try should you find yourself in this situation. As a patch to ares_init.c, it looks like
if ((_res.options & RES_INIT) == 0) res_init();
channel->nservers = _res.nscount;
channel->servers = malloc(channel->nservers * sizeof(struct server_state));
memset(channel->servers, '\0', channel->nservers * sizeof(struct server_state));
int i;
for (i = 0; i < channel->nservers; i++)
{
memcpy(&channel->servers[i].addr, &_res.nsaddr_list[i].sin_addr, sizeof(struct in_addr));
}
Excellent, excellent. It’s so nice to have competent people around to sort you out, isn’t it?
Continue Reading →NOV