diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-07-31 17:19:47 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-07-31 17:19:47 -0400 |
commit | 122c8efb09643a65cbec6c991f3433774a4524ae (patch) | |
tree | 508029b3d9ca8f7f78311c9a32f8e219520f304a /src | |
parent | ae75fb13e175ec24cb3bff44150fd2f932aa5385 (diff) | |
parent | 62637fa22405278758febb1743da9af562524d4c (diff) | |
download | tor-122c8efb09643a65cbec6c991f3433774a4524ae.tar.gz tor-122c8efb09643a65cbec6c991f3433774a4524ae.zip |
Merge branch 'bug6480_squashed' into maint-0.2.3
Diffstat (limited to 'src')
-rw-r--r-- | src/or/dns.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/or/dns.c b/src/or/dns.c index da11668c6d..3e88fad68c 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -168,7 +168,8 @@ static void add_wildcarded_test_address(const char *address); static int configure_nameservers(int force); static int answer_is_wildcarded(const char *ip); static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, - or_circuit_t *oncirc, char **resolved_to_hostname); + or_circuit_t *oncirc, char **resolved_to_hostname, + int *made_connection_pending_out); #ifdef DEBUG_DNS_CACHE static void _assert_cache_ok(void); #define assert_cache_ok() _assert_cache_ok() @@ -596,10 +597,12 @@ dns_resolve(edge_connection_t *exitconn) { or_circuit_t *oncirc = TO_OR_CIRCUIT(exitconn->on_circuit); int is_resolve, r; + int made_connection_pending = 0; char *hostname = NULL; is_resolve = exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE; - r = dns_resolve_impl(exitconn, is_resolve, oncirc, &hostname); + r = dns_resolve_impl(exitconn, is_resolve, oncirc, &hostname, + &made_connection_pending); switch (r) { case 1: @@ -639,16 +642,11 @@ dns_resolve(edge_connection_t *exitconn) dns_cancel_pending_resolve(exitconn->_base.address); - if (!exitconn->_base.marked_for_close) { + if (!made_connection_pending && !exitconn->_base.marked_for_close) { + /* 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)); - // XXX ... and we just leak exitconn otherwise? -RD - // If it's marked for close, it's on closeable_connection_lst in - // main.c. If it's on the closeable list, it will get freed from - // main.c. -NM - // "<armadev> If that's true, there are other bugs around, where we - // don't check if it's marked, and will end up double-freeing." - // On the other hand, I don't know of any actual bugs here, so this - // shouldn't be holding up the rc. -RD } break; default: @@ -667,10 +665,15 @@ dns_resolve(edge_connection_t *exitconn) * Return -2 on a transient error. If it's a reverse resolve and it's * successful, sets *<b>hostname_out</b> to a newly allocated string * holding the cached reverse DNS value. + * + * Set *<b>made_connection_pending_out</b> to true if we have placed + * <b>exitconn</b> on the list of pending connections for some resolve; set it + * to false otherwise. */ static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, - or_circuit_t *oncirc, char **hostname_out) + or_circuit_t *oncirc, char **hostname_out, + int *made_connection_pending_out) { cached_resolve_t *resolve; cached_resolve_t search; @@ -684,6 +687,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, tor_assert(!SOCKET_OK(exitconn->_base.s)); assert_cache_ok(); tor_assert(oncirc); + *made_connection_pending_out = 0; /* first check if exitconn->_base.address is an IP. If so, we already * know the answer. */ @@ -757,6 +761,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, pending_connection->conn = exitconn; pending_connection->next = resolve->pending_connections; resolve->pending_connections = pending_connection; + *made_connection_pending_out = 1; log_debug(LD_EXIT,"Connection (fd %d) waiting for pending DNS " "resolve of %s", exitconn->_base.s, escaped_safe_str(exitconn->_base.address)); @@ -797,6 +802,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, pending_connection = tor_malloc_zero(sizeof(pending_connection_t)); pending_connection->conn = exitconn; resolve->pending_connections = pending_connection; + *made_connection_pending_out = 1; /* Add this resolve to the cache and priority queue. */ HT_INSERT(cache_map, &cache_root, resolve); |