diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuitlist.c | 56 | ||||
-rw-r--r-- | src/or/circuituse.c | 2 | ||||
-rw-r--r-- | src/or/connection_edge.c | 25 | ||||
-rw-r--r-- | src/or/dns.c | 1 | ||||
-rw-r--r-- | src/or/or.h | 1 |
5 files changed, 74 insertions, 11 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 8716d10a5c..cf55b51dd2 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -32,6 +32,7 @@ static void circuit_free_cpath_node(crypt_path_t *victim); /********* END VARIABLES ************/ +/** DOCDOC This whole section */ struct orconn_circid_circuit_map_t { SPLAY_ENTRY(orconn_circid_circuit_map_t) node; connection_t *or_conn; @@ -298,8 +299,60 @@ circuit_t *circuit_get_by_circid_orconn(uint16_t circ_id, connection_t *conn) { found = SPLAY_FIND(orconn_circid_tree, &orconn_circid_circuit_map, &search); if (found && found->circuit && !found->circuit->marked_for_close) return found->circuit; - else + + /* The rest of this can be replaced with + "return NULL;" once we believe the code works. */ + + { + circuit_t *circ; + for (circ=global_circuitlist;circ;circ = circ->next) { + if (circ->marked_for_close) + continue; + + if (circ->p_conn == conn && circ->p_circ_id == circ_id) { + log_fn(LOG_WARN, "circuit matches p_conn, but not in tree (Bug!)"); + return circ; + } + if (circ->n_conn == conn && circ->n_circ_id == circ_id) { + log_fn(LOG_WARN, "circuit matches n_conn, but not in tree (Bug!)"); + return circ; + } + } return NULL; + } + +} + +/** DOCDOC */ +circuit_t *circuit_get_by_stream(connection_t *conn) +{ + circuit_t *circ; + connection_t *tmpconn; + tor_assert(CONN_IS_EDGE(conn)); + + if (! conn->on_circuit) { + /* return NULL; */ + circ = circuit_get_by_conn(conn); + if (circ) { + log_fn(LOG_WARN, "BUG: conn->on_circuit==NULL, but there was in fact a circuit there. "); + } + return circ; + } + + circ = conn->on_circuit; + /* All this stuff here is sanity-checking. */ + tor_assert(circ->magic == CIRCUIT_MAGIC); + for (tmpconn = circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream) + if (tmpconn == conn) + return circ; + for (tmpconn = circ->n_streams; tmpconn; tmpconn=tmpconn->next_stream) + if (tmpconn == conn) + return circ; + for (tmpconn = circ->resolving_streams; tmpconn; tmpconn=tmpconn->next_stream) + if (tmpconn == conn) + return circ; + + tor_assert(0); } /** Return a circ such that circ is attached to <b>conn</b>, either as @@ -505,6 +558,7 @@ void _circuit_mark_for_close(circuit_t *circ, int line, const char *file) conn->has_sent_end = 1; /* we're closing the circuit, nothing to send to */ connection_mark_for_close(conn); } + conn->on_circuit = NULL; } if (circ->p_conn) connection_send_destroy(circ->p_circ_id, circ->p_conn); diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 756baea85a..bfaafdbe82 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -417,6 +417,7 @@ void circuit_detach_stream(circuit_t *circ, connection_t *conn) { tor_assert(conn); conn->cpath_layer = NULL; /* make sure we don't keep a stale pointer */ + conn->on_circuit = NULL; if (conn == circ->p_streams) { circ->p_streams = conn->next_stream; @@ -923,6 +924,7 @@ static void link_apconn_to_circ(connection_t *apconn, circuit_t *circ) { log_fn(LOG_DEBUG,"attaching new conn to circ. n_circ_id %d.", circ->n_circ_id); apconn->timestamp_lastread = time(NULL); /* reset it, so we can measure circ timeouts */ apconn->next_stream = circ->p_streams; + apconn->on_circuit = circ; /* assert_connection_ok(conn, time(NULL)); */ circ->p_streams = apconn; diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 1e72d6f7d3..f9273d2bc2 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -142,18 +142,19 @@ int connection_edge_process_inbuf(connection_t *conn, int package_partial) { int connection_edge_destroy(uint16_t circ_id, connection_t *conn) { tor_assert(CONN_IS_EDGE(conn)); - if (conn->marked_for_close) - return 0; /* already marked; probably got an 'end' */ - log_fn(LOG_INFO,"CircID %d: At an edge. Marking connection for close.", - circ_id); - if (conn->type == CONN_TYPE_AP) { - connection_mark_unattached_ap(conn, END_STREAM_REASON_DESTROY); - } else { - conn->has_sent_end = 1; /* we're closing the circuit, nothing to send to */ - connection_mark_for_close(conn); - conn->hold_open_until_flushed = 1; + if (!conn->marked_for_close) { + log_fn(LOG_INFO,"CircID %d: At an edge. Marking connection for close.", + circ_id); + if (conn->type == CONN_TYPE_AP) { + connection_mark_unattached_ap(conn, END_STREAM_REASON_DESTROY); + } else { + conn->has_sent_end = 1; /* we're closing the circuit, nothing to send to */ + connection_mark_for_close(conn); + conn->hold_open_until_flushed = 1; + } } conn->cpath_layer = NULL; + conn->on_circuit = NULL; return 0; } @@ -1368,6 +1369,7 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) { /* add it into the linked list of n_streams on this circuit */ n_stream->next_stream = circ->n_streams; + n_stream->on_circuit = circ; circ->n_streams = n_stream; assert_circuit_ok(circ); @@ -1392,6 +1394,7 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) { /* add it into the linked list of n_streams on this circuit */ n_stream->next_stream = circ->n_streams; + n_stream->on_circuit = circ; circ->n_streams = n_stream; assert_circuit_ok(circ); @@ -1403,6 +1406,7 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) { case 0: /* resolve added to pending list */ /* add it into the linked list of resolving_streams on this circuit */ n_stream->next_stream = circ->resolving_streams; + n_stream->on_circuit = circ; circ->resolving_streams = n_stream; assert_circuit_ok(circ); ; @@ -1447,6 +1451,7 @@ int connection_exit_begin_resolve(cell_t *cell, circuit_t *circ) { return 0; case 0: /* resolve added to pending list */ dummy_conn->next_stream = circ->resolving_streams; + dummy_conn->on_circuit = circ; circ->resolving_streams = dummy_conn; assert_circuit_ok(circ); break; diff --git a/src/or/dns.c b/src/or/dns.c index 02f44697e5..1a488920e2 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -571,6 +571,7 @@ static void dns_found_answer(char *address, uint32_t addr, char outcome) { circuit_detach_stream(circ, pend->conn); /* and link it to n_streams */ pend->conn->next_stream = circ->n_streams; + pend->conn->on_circuit = circ; circ->n_streams = pend->conn; connection_exit_connect(pend->conn); diff --git a/src/or/or.h b/src/or/or.h index 1233ee721d..1a07ee0884 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -629,6 +629,7 @@ struct connection_t { int done_receiving; /**< For half-open connections; not used currently. */ char has_sent_end; /**< For debugging: set once we've set the stream end, and check in circuit_about_to_close_connection(). */ + struct circuit_t *on_circuit; /**< DOCDOC */ /* Used only by AP connections */ socks_request_t *socks_request; /**< SOCKS structure describing request (AP |