int dns_forward_query_tcp(event_entry_t *general_entry) { struct event_tcp_entry *entry = &general_entry->tcp; if (!ip_tcp_open(&entry->intsock, &global_target_address)) { debug_log(DEBUG_ERROR, "dns_forward_query_tcp(): unable to open TCP socket\n"); goto wrong; } // randomizing port is not really necessary, as TCP is invulnerable to cache poisoning // however, the source IP address is set in ip_bind_random... if (!ip_bind_random(entry->intsock)) { // if this fails, let the kernel handle it (would mean source IP address is not guaranteed...) debug_log(DEBUG_WARN, "dns_forward_query_tcp(): unable to bind to source IP address and/or random port\n"); } if (!ip_connect(entry->intsock, &global_target_address)) { debug_log(DEBUG_ERROR, "dns_forward_query_tcp(): unable to connect to authoritative name server (%s)\n", strerror(errno)); goto wrong; } // Now generate a new TXID to forecome any poisoning: entry->buffer[0] = misc_crypto_random(256); entry->buffer[1] = misc_crypto_random(256); // XXX: do this platform safe (i.e. ntoh) entry->dns.dsttxid = (entry->buffer[0] << 8) + entry->buffer[1]; debug_log(DEBUG_INFO, "dns_forward_query_tcp(): forwarding query to authoritative name server (prev id = %d, new id = %d)\n", entry->dns.srctxid, entry->dns.dsttxid); return 1; wrong: return 0; }
int dns_forward_query_udp(event_entry_t *general_entry) { int sock, n; struct event_udp_entry *entry = &general_entry->udp; if (!ip_udp_open(&sock, &global_target_address)) { debug_log(DEBUG_ERROR, "dns_forward_query_udp(): unable to open a UDP socket to forward query to authoritative server\n"); goto wrong; } // randomize the outgoing source port and set the source IP address, if needed if (!ip_bind_random(sock)) { // if this fails, let the kernel handle it (would mean source IP address is not guaranteed...) debug_log(DEBUG_WARN, "dns_forward_query_udp(): unable to bind to source IP address and/or random port\n"); } entry->state = EVENT_UDP_INT_WRITING; entry->read_int_watcher.data = general_entry; entry->timeout_int_watcher.data = general_entry; entry->retries++; // Now generate a new TXID to forecome any poisoning: entry->buffer[0] = misc_crypto_random(256); entry->buffer[1] = misc_crypto_random(256); // XXX: do this platform safe (i.e. ntoh) entry->dns.dsttxid = (entry->buffer[0] << 8) + entry->buffer[1]; ev_io_init(&entry->read_int_watcher, event_udp_int_cb, sock, EV_READ); ev_timer_init(&entry->timeout_int_watcher, event_udp_timeout_cb, 0., global_ip_internal_timeout); ev_io_start(event_default_loop, &entry->read_int_watcher); ev_timer_again(event_default_loop, &entry->timeout_int_watcher); debug_log(DEBUG_INFO, "dns_forward_query_udp(): forwarding query to authoritative name server (prev id = %d, new id = %d)\n", (entry->dns.type == DNS_DNSCURVE_STREAMLINED || entry->dns.type == DNS_NON_DNSCURVE) ? entry->dns.srctxid : entry->dns.srcinsidetxid, entry->dns.dsttxid); n = sendto(sock, entry->buffer, entry->packetsize, MSG_DONTWAIT, (struct sockaddr *) &global_target_address.sa, global_target_address_len); if (n == -1) { debug_log(DEBUG_ERROR, "dns_forward_query_udp(): unable to forward the query to authoritative name server (%s)\n", strerror(errno)); goto wrong; } return 1; wrong: return 0; }