summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-06-01 22:09:58 +0000
committerNick Mathewson <nickm@torproject.org>2004-06-01 22:09:58 +0000
commit0d20fee2fbd48978f631175fee71f8f74908b359 (patch)
treeba9b19bfebbf17c8540852c13ebeaa4a4e43bd92
parent94782444f80f483bafebf537b059f2d8a8e0cdd2 (diff)
downloadtor-0d20fee2fbd48978f631175fee71f8f74908b359.tar.gz
tor-0d20fee2fbd48978f631175fee71f8f74908b359.zip
Add more asserts to dns-pending connections; fix a couple seeming bugs.
svn:r1931
-rw-r--r--src/or/dns.c27
-rw-r--r--src/or/main.c10
-rw-r--r--src/or/or.h1
3 files changed, 34 insertions, 4 deletions
diff --git a/src/or/dns.c b/src/or/dns.c
index 0106c4d814..964230f722 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 f6709cd2f3..b63dd1439b 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 eb9ee85a5a..d1fd6e9761 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);