Здесь код из моего поста, который уже был упомянут выше, просто немного адаптирован для использования IPv6.
Адаптируйте setup_dns_server
Сначала мы можем начать с измененийв setup_dns_server:
void setup_dns_server(res_state res, const char *dns_server) {
struct in6_addr addr;
inet_pton(AF_INET6, dns_server, &addr);
res->_u._ext.ext->nsaddrs[0].sin6.sin6_addr = addr;
res->_u._ext.ext->nsaddrs[0].sin6.sin6_family = AF_INET6;
res->_u._ext.ext->nsaddrs[0].sin6.sin6_port = htons(NS_DEFAULTPORT);
res->nscount = 1;
}
Добавить __res_state_ext
Это не скомпилируется из-за отсутствия структуры __res_state_ext.К сожалению, эта структура находится в частном заголовочном файле.
Но определение этого можно взять отсюда: https://opensource.apple.com/source/libresolv/libresolv-65/res_private.h.auto.html:
struct __res_state_ext {
union res_sockaddr_union nsaddrs[MAXNS];
struct sort_list {
int af;
union {
struct in_addr ina;
struct in6_addr in6a;
} addr, mask;
} sort_list[MAXRESOLVSORT];
char nsuffix[64];
char bsuffix[64];
char nsuffix2[64];
};
Структура может быть добавлена, например:вверху файла.
Адаптировать resolHost
Изменения включают более длинный буфер для ip (INET6_ADDRSTRLEN).res_ninit перемещен из setup_dns_server в этот метод и теперь сопоставляется с res_ndestroy.
+ (NSString *)resolveHost:(NSString *)host usingDNSServer:(NSString *)dnsServer {
struct __res_state res;
char ip[INET6_ADDRSTRLEN];
memset(ip, '\0', sizeof(ip));
res_ninit(&res);
setup_dns_server(&res, [dnsServer cStringUsingEncoding:NSASCIIStringEncoding]);
query_ip(&res, [host cStringUsingEncoding:NSUTF8StringEncoding], ip);
res_ndestroy(&res);
return [[NSString alloc] initWithCString:ip encoding:NSASCIIStringEncoding];
}
Извлечение адресов IPv6
Изменения выше уже достаточны, если вы просто хотитеиспользуйте IPv6-адрес для вашего DNS-сервера.Таким образом, в query_ip нет необходимости вносить изменения, если вы все еще хотите получить адреса IPv4.
Если вы хотите получить IPv6-адреса также с DNS-сервера, вы можете сделать это:
void query_ip(res_state res, const char *host, char ip[]) {
u_char answer[NS_PACKETSZ];
int len = res_nquery(res, host, ns_c_in, ns_t_aaaa, answer, sizeof(answer));
ns_msg handle;
ns_initparse(answer, len, &handle);
if(ns_msg_count(handle, ns_s_an) > 0) {
ns_rr rr;
if(ns_parserr(&handle, ns_s_an, 0, &rr) == 0) {
inet_ntop(AF_INET6, ns_rr_rdata(rr), ip, INET6_ADDRSTRLEN);
}
}
}
Обратите внимание: мы используем здесь ns_t_aaaa для получения записей ресурсов AAAA (quad-Запись), потому что в DNS это указывает на соответствие между адресом IPv6 и именем хоста.Для многих хостов такой записи quad-A нет, то есть вы можете просто связаться с ними через IPv4.
Call
Вы можете назвать это, например, так:
NSString *resolved = [ResolveUtil resolveHost:@"www.google.com" usingDNSServer:@"2001:4860:4860::8888"];
NSLog(@"%@", resolved);
Результат будет выглядеть следующим образом:
Отказ от ответственности
Это просто простые примеры вызовов, которые демонстрируют основное использование функций.Там нет обработки ошибок.