aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-10-27 16:34:49 -0400
committerNick Mathewson <nickm@torproject.org>2012-11-14 23:16:23 -0500
commitb7843ca5544e741e74fe5f93fb49579e01b468c8 (patch)
treef1397706d25d1ba0f7060a89fcfeb72154026971
parent00633b944672458bdfd3d79bab4e1230cee4a522 (diff)
downloadtor-b7843ca5544e741e74fe5f93fb49579e01b468c8.tar
tor-b7843ca5544e741e74fe5f93fb49579e01b468c8.tar.gz
Make DNS callback pass IPv6 answers to dns_answer_found
Also, count ipv6 timeouts vs others. If we have too many ipv6 requests time out, then we could be degrading performance because of a broken DNS server that ignores AAAA requests. Other cases in which we never learn an AAAA address aren't so bad, since they don't slow A (ipv4) answers down very much.
-rw-r--r--src/or/dns.c74
-rw-r--r--src/or/dns.h1
2 files changed, 68 insertions, 7 deletions
diff --git a/src/or/dns.c b/src/or/dns.c
index c590e01da..383242100 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -1342,6 +1342,10 @@ configure_nameservers(int force)
return -1;
}
+static uint64_t n_ipv6_requests_made = 0;
+static uint64_t n_ipv6_timeouts = 0;
+static int dns_is_broken_for_ipv6 = 0;
+
/** For eventdns: Called when we get an answer for a request we launched.
* See eventdns.h for arguments; 'arg' holds the address we tried to resolve.
*/
@@ -1352,20 +1356,39 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses,
char *string_address = arg;
uint8_t is_reverse = 0;
int status = DNS_RESOLVE_FAILED_PERMANENT;
- uint32_t addr = 0;
+ tor_addr_t addr;
const char *hostname = NULL;
int was_wildcarded = 0;
+ tor_addr_make_unspec(&addr); /*WRONG WRONG WRONG XXXX XXXXX IPV6 prop208*/
+
+ /* Keep track of whether IPv6 is working */
+ if (type == DNS_IPv6_AAAA) {
+ if (result == DNS_ERR_TIMEOUT) {
+ ++n_ipv6_timeouts;
+ }
+
+ if (n_ipv6_timeouts > 10 &&
+ n_ipv6_timeouts > n_ipv6_requests_made / 2) {
+ if (! dns_is_broken_for_ipv6) {
+ log_notice(LD_EXIT, "More than half of our IPv6 requests seem to "
+ "have timed out. I'm going to assume I can't get AAAA "
+ "responses.");
+ dns_is_broken_for_ipv6 = 1;
+ }
+ }
+ }
+
if (result == DNS_ERR_NONE) {
if (type == DNS_IPv4_A && count) {
char answer_buf[INET_NTOA_BUF_LEN+1];
struct in_addr in;
char *escaped_address;
uint32_t *addrs = addresses;
- in.s_addr = addrs[0];
- addr = ntohl(addrs[0]);
+ tor_addr_from_ipv4n(&addr, addrs[0]);
status = DNS_RESOLVE_SUCCEEDED;
- tor_inet_ntoa(&in, answer_buf, sizeof(answer_buf));
+
+ tor_addr_to_str(answer_buf, &addr, sizeof(answer_buf), 0);
escaped_address = esc_for_log(string_address);
if (answer_is_wildcarded(answer_buf)) {
@@ -1382,6 +1405,29 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses,
escaped_safe_str(answer_buf));
}
tor_free(escaped_address);
+ } else if (type == DNS_IPv6_AAAA && count) {
+ char answer_buf[TOR_ADDR_BUF_LEN];
+ char *escaped_address;
+ struct in6_addr *addrs = addresses;
+ tor_addr_from_in6(&addr, &addrs[0]);
+ status = DNS_RESOLVE_SUCCEEDED;
+ tor_inet_ntop(AF_INET6, &addrs[0], answer_buf, sizeof(answer_buf));
+ escaped_address = esc_for_log(string_address);
+
+ if (answer_is_wildcarded(answer_buf)) {
+ log_debug(LD_EXIT, "eventdns said that %s resolves to ISP-hijacked "
+ "address %s; treating as a failure.",
+ safe_str(escaped_address),
+ escaped_safe_str(answer_buf));
+ was_wildcarded = 1;
+ tor_addr_make_unspec(&addr); /* WRONG WRONG ETC XXXXXXXX */
+ status = DNS_RESOLVE_FAILED_PERMANENT;
+ } else {
+ log_debug(LD_EXIT, "eventdns said that %s resolves to %s",
+ safe_str(escaped_address),
+ escaped_safe_str(answer_buf));
+ }
+ tor_free(escaped_address);
} else if (type == DNS_PTR && count) {
char *escaped_address;
is_reverse = 1;
@@ -1666,8 +1712,8 @@ launch_test_addresses(int fd, short event, void *args)
/* This situation is worse than the failure-hijacking situation. When this
* happens, we're no good for DNS requests at all, and we shouldn't really
* be an exit server.*/
- if (!options->ServerDNSTestAddresses)
- return;
+ if (options->ServerDNSTestAddresses) {
+
tor_assert(the_evdns_base);
SMARTLIST_FOREACH_BEGIN(options->ServerDNSTestAddresses,
const char *, address) {
@@ -1683,12 +1729,16 @@ launch_test_addresses(int fd, short event, void *args)
a = tor_strdup(address);
req = evdns_base_resolve_ipv6(the_evdns_base,
address, DNS_QUERY_NO_SEARCH, evdns_callback, a);
+ ++n_ipv6_requests_made;
if (!req) {
log_info(LD_EXIT, "eventdns rejected test address %s",
escaped_safe_str(address));
tor_free(a);
}
} SMARTLIST_FOREACH_END(address);
+
+ } /*XXXX REINDENT */
+
}
#define N_WILDCARD_CHECKS 2
@@ -1756,6 +1806,13 @@ dns_seems_to_be_broken(void)
return dns_is_completely_invalid;
}
+/** DOCDOC */
+int
+dns_seems_to_be_broken_for_ipv6(void)
+{
+ return dns_is_broken_for_ipv6;
+}
+
/** Forget what we've previously learned about our DNS servers' correctness. */
void
dns_reset_correctness_checks(void)
@@ -1765,6 +1822,8 @@ dns_reset_correctness_checks(void)
n_wildcard_requests = 0;
+ n_ipv6_requests_made = n_ipv6_timeouts = 0;
+
if (dns_wildcard_list) {
SMARTLIST_FOREACH(dns_wildcard_list, char *, cp, tor_free(cp));
smartlist_clear(dns_wildcard_list);
@@ -1775,7 +1834,8 @@ dns_reset_correctness_checks(void)
smartlist_clear(dns_wildcarded_test_address_list);
}
dns_wildcard_one_notice_given = dns_wildcard_notice_given =
- dns_wildcarded_test_address_notice_given = dns_is_completely_invalid = 0;
+ dns_wildcarded_test_address_notice_given = dns_is_completely_invalid =
+ dns_is_broken_for_ipv6 = 0;
}
/** Return true iff we have noticed that the dotted-quad <b>ip</b> has been
diff --git a/src/or/dns.h b/src/or/dns.h
index 441a6c350..d2f6614e6 100644
--- a/src/or/dns.h
+++ b/src/or/dns.h
@@ -24,6 +24,7 @@ void dns_cancel_pending_resolve(const char *question);
int dns_resolve(edge_connection_t *exitconn);
void dns_launch_correctness_checks(void);
int dns_seems_to_be_broken(void);
+int dns_seems_to_be_broken_for_ipv6(void);
void dns_reset_correctness_checks(void);
void dump_dns_mem_usage(int severity);