diff options
Diffstat (limited to 'src/or/dns.c')
-rw-r--r-- | src/or/dns.c | 71 |
1 files changed, 43 insertions, 28 deletions
diff --git a/src/or/dns.c b/src/or/dns.c index 33628373d5..ba734ed900 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2016, The Tor Project, Inc. */ + * Copyright (c) 2007-2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -19,7 +19,7 @@ * dns_seems_to_be_broken(). * <li>When a client has asked the relay, in a RELAY_BEGIN cell, to connect * to a given server by hostname. This happens via dns_resolve(). - * <li>When a client has asked the rela, in a RELAY_RESOLVE cell, to look + * <li>When a client has asked the relay, in a RELAY_RESOLVE cell, to look * up a given server's IP address(es) by hostname. This also happens via * dns_resolve(). * </ol> @@ -56,6 +56,7 @@ #include "connection.h" #include "connection_edge.h" #include "control.h" +#include "crypto_rand.h" #include "dns.h" #include "main.h" #include "policies.h" @@ -102,7 +103,7 @@ static void assert_cache_ok_(void); #define assert_cache_ok() assert_cache_ok_() #else #define assert_cache_ok() STMT_NIL -#endif +#endif /* defined(DEBUG_DNS_CACHE) */ static void assert_resolve_ok(cached_resolve_t *resolve); /** Hash table of cached_resolve objects. */ @@ -160,8 +161,9 @@ evdns_log_cb(int warn, const char *msg) } if (!strcmpstart(msg, "Nameserver ") && (cp=strstr(msg, " has failed: "))) { char *ns = tor_strndup(msg+11, cp-(msg+11)); - const char *err = strchr(cp, ':')+2; - tor_assert(err); + const char *colon = strchr(cp, ':'); + tor_assert(colon); + const char *err = colon+2; /* Don't warn about a single failed nameserver; we'll warn with 'all * nameservers have failed' if we're completely out of nameservers; * otherwise, the situation is tolerable. */ @@ -181,6 +183,18 @@ evdns_log_cb(int warn, const char *msg) } else if (!strcmp(msg, "All nameservers have failed")) { control_event_server_status(LOG_WARN, "NAMESERVER_ALL_DOWN"); all_down = 1; + } else if (!strcmpstart(msg, "Address mismatch on received DNS")) { + static ratelim_t mismatch_limit = RATELIM_INIT(3600); + const char *src = strstr(msg, " Apparent source"); + if (!src || get_options()->SafeLogging) { + src = ""; + } + log_fn_ratelim(&mismatch_limit, severity, LD_EXIT, + "eventdns: Received a DNS packet from " + "an IP address to which we did not send a request. This " + "could be a DNS spoofing attempt, or some kind of " + "misconfiguration.%s", src); + return; } tor_log(severity, LD_EXIT, "eventdns: %s", msg); } @@ -365,7 +379,7 @@ set_expiry(cached_resolve_t *resolve, time_t expires) resolve->expire = expires; smartlist_pqueue_add(cached_resolve_pqueue, compare_cached_resolves_by_expiry_, - STRUCT_OFFSET(cached_resolve_t, minheap_idx), + offsetof(cached_resolve_t, minheap_idx), resolve); } @@ -412,7 +426,7 @@ purge_expired_resolves(time_t now) break; smartlist_pqueue_pop(cached_resolve_pqueue, compare_cached_resolves_by_expiry_, - STRUCT_OFFSET(cached_resolve_t, minheap_idx)); + offsetof(cached_resolve_t, minheap_idx)); if (resolve->state == CACHE_STATE_PENDING) { log_debug(LD_EXIT, @@ -444,7 +458,7 @@ purge_expired_resolves(time_t now) if (!pendconn->base_.marked_for_close) { connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT); circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn); - connection_free(TO_CONN(pendconn)); + connection_free_(TO_CONN(pendconn)); } tor_free(pend); } @@ -657,7 +671,7 @@ dns_resolve(edge_connection_t *exitconn) /* If we made the connection pending, then we freed it already in * dns_cancel_pending_resolve(). If we marked it for close, it'll * get freed from the main loop. Otherwise, can free it now. */ - connection_free(TO_CONN(exitconn)); + connection_free_(TO_CONN(exitconn)); } break; default: @@ -948,14 +962,14 @@ assert_connection_edge_not_dns_pending(edge_connection_t *conn) for (pend = resolve->pending_connections; pend; pend = pend->next) { tor_assert(pend->conn != conn); } -#else +#else /* !(1) */ cached_resolve_t **resolve; HT_FOREACH(resolve, cache_map, &cache_root) { for (pend = (*resolve)->pending_connections; pend; pend = pend->next) { tor_assert(pend->conn != conn); } } -#endif +#endif /* 1 */ } /** Log an error and abort if any connection waiting for a DNS resolve is @@ -1088,7 +1102,7 @@ dns_cancel_pending_resolve,(const char *address)) if (circ) circuit_detach_stream(circ, pendconn); if (!pendconn->base_.marked_for_close) - connection_free(TO_CONN(pendconn)); + connection_free_(TO_CONN(pendconn)); resolve->pending_connections = pend->next; tor_free(pend); } @@ -1217,7 +1231,7 @@ inform_pending_connections(cached_resolve_t *resolve) /* This detach must happen after we send the resolved cell. */ circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn); } - connection_free(TO_CONN(pendconn)); + connection_free_(TO_CONN(pendconn)); } else { circuit_t *circ; if (pendconn->base_.purpose == EXIT_PURPOSE_CONNECT) { @@ -1246,7 +1260,7 @@ inform_pending_connections(cached_resolve_t *resolve) circ = circuit_get_by_edge_conn(pendconn); tor_assert(circ); circuit_detach_stream(circ, pendconn); - connection_free(TO_CONN(pendconn)); + connection_free_(TO_CONN(pendconn)); } } resolve->pending_connections = pend->next; @@ -1383,7 +1397,7 @@ configure_nameservers(int force) evdns_base_load_hosts(the_evdns_base, sandbox_intern_string("/etc/hosts")); } -#endif +#endif /* defined(DNS_OPTION_HOSTSFILE) && defined(USE_LIBSECCOMP) */ log_info(LD_EXIT, "Parsing resolver configuration in '%s'", conf_fname); if ((r = evdns_base_resolv_conf_parse(the_evdns_base, flags, sandbox_intern_string(conf_fname)))) { @@ -1421,7 +1435,7 @@ configure_nameservers(int force) tor_free(resolv_conf_fname); resolv_conf_mtime = 0; } -#endif +#endif /* defined(_WIN32) */ #define SET(k,v) evdns_base_set_option(the_evdns_base, (k), (v)) @@ -1568,10 +1582,11 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses, escaped_safe_str(hostname)); tor_free(escaped_address); } else if (count) { - log_warn(LD_EXIT, "eventdns returned only non-IPv4 answers for %s.", + log_info(LD_EXIT, "eventdns returned only unrecognized answer types " + " for %s.", escaped_safe_str(string_address)); } else { - log_warn(LD_BUG, "eventdns returned no addresses or error for %s!", + log_info(LD_EXIT, "eventdns returned no addresses or error for %s.", escaped_safe_str(string_address)); } } @@ -1655,7 +1670,7 @@ launch_resolve,(cached_resolve_t *resolve)) tor_addr_t a; int r; - if (get_options()->DisableNetwork) + if (net_is_disabled()) return -1; /* What? Nameservers not configured? Sounds like a bug. */ @@ -1762,7 +1777,7 @@ wildcard_increment_answer(const char *id) "invalid addresses. Apparently they are hijacking DNS failures. " "I'll try to correct for this by treating future occurrences of " "\"%s\" as 'not found'.", id, *ip, id); - smartlist_add(dns_wildcard_list, tor_strdup(id)); + smartlist_add_strdup(dns_wildcard_list, id); } if (!dns_wildcard_notice_given) control_event_server_status(LOG_NOTICE, "DNS_HIJACKED"); @@ -1786,7 +1801,7 @@ add_wildcarded_test_address(const char *address) n_test_addrs = get_options()->ServerDNSTestAddresses ? smartlist_len(get_options()->ServerDNSTestAddresses) : 0; - smartlist_add(dns_wildcarded_test_address_list, tor_strdup(address)); + smartlist_add_strdup(dns_wildcarded_test_address_list, address); n = smartlist_len(dns_wildcarded_test_address_list); if (n > n_test_addrs/2) { tor_log(dns_wildcarded_test_address_notice_given ? LOG_INFO : LOG_NOTICE, @@ -1890,7 +1905,7 @@ launch_test_addresses(evutil_socket_t fd, short event, void *args) (void)event; (void)args; - if (options->DisableNetwork) + if (net_is_disabled()) return; log_info(LD_EXIT, "Launching checks to see whether our nameservers like to " @@ -1947,7 +1962,7 @@ dns_launch_wildcard_checks(void) launch_wildcard_check(8, 16, ipv6, ".com"); launch_wildcard_check(8, 16, ipv6, ".org"); launch_wildcard_check(8, 16, ipv6, ".net"); - } + } } } @@ -2040,7 +2055,7 @@ assert_resolve_ok(cached_resolve_t *resolve) tor_assert(!resolve->hostname); else tor_assert(!resolve->result_ipv4.addr_ipv4); -#endif +#endif /* 0 */ /*XXXXX ADD MORE */ } } @@ -2090,7 +2105,7 @@ assert_cache_ok_(void) smartlist_pqueue_assert_ok(cached_resolve_pqueue, compare_cached_resolves_by_expiry_, - STRUCT_OFFSET(cached_resolve_t, minheap_idx)); + offsetof(cached_resolve_t, minheap_idx)); SMARTLIST_FOREACH(cached_resolve_pqueue, cached_resolve_t *, res, { @@ -2104,10 +2119,10 @@ assert_cache_ok_(void) }); } -#endif +#endif /* defined(DEBUG_DNS_CACHE) */ -cached_resolve_t -*dns_get_cache_entry(cached_resolve_t *query) +cached_resolve_t * +dns_get_cache_entry(cached_resolve_t *query) { return HT_FIND(cache_map, &cache_root, query); } |