diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-06-01 22:09:58 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-06-01 22:09:58 +0000 |
commit | 0d20fee2fbd48978f631175fee71f8f74908b359 (patch) | |
tree | ba9b19bfebbf17c8540852c13ebeaa4a4e43bd92 /src/or | |
parent | 94782444f80f483bafebf537b059f2d8a8e0cdd2 (diff) | |
download | tor-0d20fee2fbd48978f631175fee71f8f74908b359.tar tor-0d20fee2fbd48978f631175fee71f8f74908b359.tar.gz |
Add more asserts to dns-pending connections; fix a couple seeming bugs.
svn:r1931
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/dns.c | 27 | ||||
-rw-r--r-- | src/or/main.c | 10 | ||||
-rw-r--r-- | src/or/or.h | 1 |
3 files changed, 34 insertions, 4 deletions
diff --git a/src/or/dns.c b/src/or/dns.c index 0106c4d81..964230f72 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -103,6 +103,8 @@ static struct cached_resolve *newest_cached_resolve = NULL; * from the cache. */ static void purge_expired_resolves(uint32_t now) { struct cached_resolve *resolve; + struct pending_connection_t *pend; + connection_t *pendconn; /* this is fast because the linked list * oldest_cached_resolve is ordered by when they came in. @@ -112,9 +114,21 @@ static void purge_expired_resolves(uint32_t now) { log(LOG_DEBUG,"Forgetting old cached resolve (expires %lu)", (unsigned long)resolve->expire); if(resolve->state == CACHE_STATE_PENDING) { log_fn(LOG_WARN,"Expiring a dns resolve that's still pending. Forgot to cull it?"); - /* XXX if resolve->pending_connections is used, then we're probably - * introducing bugs by closing resolve without notifying those streams. - */ + } + if (resolve->pending_connections) { + log_fn(LOG_WARN, "Closing pending connections on expiring DNS resolve!"); + while (resolve->pending_connections) { + pend = resolve->pending_connections; + resolve->pending_connections = pend->next; + /* Connections should only be pending if they have no socket. */ + tor_assert(pend->conn->s == -1); + pendconn = pend->conn; + connection_edge_end(pendconn, END_STREAM_REASON_MISC, + pendconn->cpath_layer); + connection_mark_for_close(pendconn); + connection_free(pendconn); + tor_free(pend); + } } oldest_cached_resolve = resolve->next; if(!oldest_cached_resolve) /* if there are no more, */ @@ -141,6 +155,7 @@ int dns_resolve(connection_t *exitconn) { struct in_addr in; uint32_t now = time(NULL); assert_connection_ok(exitconn, 0); + tor_assert(exitconn->s == -1); /* first check if exitconn->address is an IP. If so, we already * know the answer. */ @@ -213,6 +228,7 @@ static int assign_to_dnsworker(connection_t *exitconn) { unsigned char len; tor_assert(exitconn->state == EXIT_CONN_STATE_RESOLVING); + tor_assert(exitconn->s == -1); spawn_enough_dnsworkers(); /* respawn here, to be sure there are enough */ @@ -309,6 +325,8 @@ void assert_all_pending_dns_resolves_ok(void) { pend; pend = pend->next) { assert_connection_ok(pend->conn, 0); + tor_assert(pend->conn->s == -1); + tor_assert(!connection_in_array(pend->conn)); } } } @@ -343,10 +361,12 @@ void dns_cancel_pending_resolve(char *address) { pend->conn->state = EXIT_CONN_STATE_RESOLVEFAILED; pendconn = pend->conn; /* don't pass complex things to the connection_mark_for_close macro */ + tor_assert(pendconn->s == -1); if(!pendconn->marked_for_close) { connection_edge_end(pendconn, END_STREAM_REASON_MISC, pendconn->cpath_layer); connection_mark_for_close(pendconn); } + connection_free(pendconn); resolve->pending_connections = pend->next; tor_free(pend); } @@ -430,7 +450,6 @@ static void dns_found_answer(char *address, uint32_t addr, char outcome) { assert_connection_ok(pend->conn,time(NULL)); pend->conn->addr = resolve->addr; - if(resolve->state == CACHE_STATE_FAILED) { pendconn = pend->conn; /* don't pass complex things to the connection_mark_for_close macro */ diff --git a/src/or/main.c b/src/or/main.c index f6709cd2f..b63dd1439 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -127,6 +127,16 @@ int connection_remove(connection_t *conn) { return 0; } +/** Return true iff conn is in the current poll array. */ +int connection_in_array(connection_t *conn) { + int i; + for (i=0; i<nfds; ++i) { + if (conn==connection_array[i]) + return 1; + } + return 0; +} + /** Set <b>*array</b> to an array of all connections, and <b>*n</b> * to the length of the array. <b>*array</b> and <b>*n</b> must not * be modified. diff --git a/src/or/or.h b/src/or/or.h index eb9ee85a5..d1fd6e976 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1125,6 +1125,7 @@ int dns_resolve(connection_t *exitconn); int connection_add(connection_t *conn); int connection_remove(connection_t *conn); +int connection_in_array(connection_t *conn); void get_connection_array(connection_t ***array, int *n); |