int resolv_init(struct ev_loop *loop, char **nameservers, int nameserver_num, int ipv6first) { if (ipv6first) resolv_mode = MODE_IPV6_FIRST; else resolv_mode = MODE_IPV4_FIRST; struct dns_ctx *ctx = &dns_defctx; if (nameservers == NULL) { /* Nameservers not specified, use system resolver config */ dns_init(ctx, 0); } else { dns_reset(ctx); for (int i = 0; i < nameserver_num; i++) { char *server = nameservers[i]; dns_add_serv(ctx, server); } } int sockfd = dns_open(ctx); if (sockfd < 0) { FATAL("Failed to open DNS resolver socket"); } if (nameserver_num == 1 && nameservers != NULL) { if (strncmp("127.0.0.1", nameservers[0], 9) == 0 || strncmp("::1", nameservers[0], 3) == 0) { if (verbose) { LOGI("bind UDP resolver to %s", nameservers[0]); } if (bind_to_address(sockfd, nameservers[0]) == -1) ERROR("bind_to_address"); } } #ifdef __MINGW32__ setnonblocking(sockfd); #else int flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); #endif ev_io_init(&resolv_io_watcher, resolv_sock_cb, sockfd, EV_READ); resolv_io_watcher.data = ctx; ev_io_start(loop, &resolv_io_watcher); ev_timer_init(&resolv_timeout_watcher, resolv_timeout_cb, 0.0, 0.0); resolv_timeout_watcher.data = ctx; dns_set_tmcbck(ctx, dns_timer_setup_cb, loop); return sockfd; }
int dns_init(struct dns_ctx *ctx, int do_open) { if (!ctx) ctx = &dns_defctx; dns_reset(ctx); #ifdef WINDOWS if (dns_initns_iphlpapi(ctx) != 0) dns_initns_registry(ctx); /*XXX WINDOWS: probably good to get default domain and search list too... * And options. Something is in registry. */ /*XXX WINDOWS: maybe environment variables are also useful? */ #else dns_init_resolvconf(ctx); #endif return do_open ? dns_open(ctx) : 0; }