int NeubotPoller_resolve(struct NeubotPoller *poller, const char *family, const char *address, neubot_hook_vos callback, void *opaque) { struct ResolveContext *rc; int result; (void) poller; rc = calloc(1, sizeof (*rc)); if (rc == NULL) { neubot_warn("resolve: calloc() failed"); goto failure; } rc->callback = callback; rc->opaque = opaque; rc->names = evbuffer_new(); if (rc->names == NULL) { neubot_warn("resolve: evbuffer_new() failed"); goto failure; } if (strcmp(family, "PF_INET6") == 0) result = evdns_resolve_ipv6(address, DNS_QUERY_NO_SEARCH, NeubotPoller_resolve_callback_internal, rc); else if (strcmp(family, "PF_INET") == 0) result = evdns_resolve_ipv4(address, DNS_QUERY_NO_SEARCH, NeubotPoller_resolve_callback_internal, rc); else { neubot_warn("resolve: invalid family"); goto failure; } if (result != 0) { neubot_warn("resolve: evdns_resolve_ipvX() failed"); goto failure; } return (0); failure: if (rc != NULL && rc->names != NULL) evbuffer_free(rc->names); if (rc != NULL) free(rc); return (-1); }
static void dns_gethostbyname6(void) { dns_ok = 0; evdns_resolve_ipv6("www.ietf.org", 0, dns_gethostbyname_cb, NULL); event_dispatch(); if (!dns_ok && dns_err == DNS_ERR_TIMEOUT) { tt_skip(); } tt_int_op(dns_ok, ==, DNS_IPv6_AAAA); test_ok = 1; end: ; }
static void dns_gethostbyname6(void) { fprintf(stdout, "IPv6 DNS resolve: "); dns_ok = 0; evdns_resolve_ipv6("www.ietf.org", 0, dns_gethostbyname_cb, NULL); event_dispatch(); if (dns_ok == DNS_IPv6_AAAA) { fprintf(stdout, "OK\n"); } else if (!dns_ok && dns_err == DNS_ERR_TIMEOUT) { fprintf(stdout, "SKIPPED\n"); } else { fprintf(stdout, "FAILED (%d)\n", dns_ok); exit(1); } }
static void dns_ipv4_done_cb( int err, char type, int count, int ttl, void * addresses, void * vtask ) { struct tr_web_task * task = vtask; if( !err && task->host && ( count>0 ) && ( ttl>=0 ) && ( type==DNS_IPv4_A ) ) { struct in_addr * in_addrs = addresses; const char * resolved = inet_ntoa( in_addrs[0] ); task->resolved_host = dns_cache_set_name( task, task->host, resolved, ttl ); /* FIXME: if count > 1, is there a way to decide which is best to use? */ } if( ( task->resolved_host != NULL ) || ( task->host == NULL ) || evdns_resolve_ipv6( task->host, 0, dns_ipv6_done_cb, task ) ) dns_ipv6_done_cb( DNS_ERR_UNKNOWN, DNS_IPv6_AAAA, 0, 0, NULL, task ); }
static void dns_server(void) { int sock; struct sockaddr_in my_addr; struct evdns_server_port *port; struct in_addr resolve_addr; dns_ok = 1; fprintf(stdout, "DNS server support: "); /* Add ourself as the only nameserver, and make sure we really are * the only nameserver. */ evdns_nameserver_ip_add("127.0.0.1:35353"); if (evdns_count_nameservers() != 1) { fprintf(stdout, "Couldn't set up.\n"); exit(1); } /* Now configure a nameserver port. */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) { perror("socket"); exit(1); } #ifdef WIN32 { u_long nonblocking = 1; ioctlsocket(sock, FIONBIO, &nonblocking); } #else fcntl(sock, F_SETFL, O_NONBLOCK); #endif memset(&my_addr, 0, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(35353); my_addr.sin_addr.s_addr = htonl(0x7f000001UL); if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) { perror("bind"); exit (1); } port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL); /* Send two queries. */ evdns_resolve_ipv4("zz.example.com", DNS_QUERY_NO_SEARCH, dns_server_gethostbyname_cb, NULL); evdns_resolve_ipv6("zz.example.com", DNS_QUERY_NO_SEARCH, dns_server_gethostbyname_cb, NULL); resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */ evdns_resolve_reverse(&resolve_addr, 0, dns_server_gethostbyname_cb, NULL); event_dispatch(); if (dns_ok) { fprintf(stdout, "OK\n"); } else { fprintf(stdout, "FAILED\n"); exit(1); } evdns_close_server_port(port); evdns_shutdown(0); /* remove ourself as nameserver. */ #ifdef WIN32 closesocket(sock); #else close(sock); #endif }