diff options
author | Roger Dingledine <arma@torproject.org> | 2007-05-10 08:53:05 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2007-05-10 08:53:05 +0000 |
commit | 5ffabd4de4ee61fc0027b3fb82f7db22d96e661d (patch) | |
tree | ca8b4e3581131bd6b7abdcb98df3e7c039b83435 /src/or/connection_edge.c | |
parent | cd23b65a0771ddfb1b40aae126a3abd2bf33dadf (diff) | |
download | tor-5ffabd4de4ee61fc0027b3fb82f7db22d96e661d.tar.gz tor-5ffabd4de4ee61fc0027b3fb82f7db22d96e661d.zip |
backport candidate:
If a directory server runs out of space in the connection table
as it's processing a begin_dir request, it will free the exit stream
but leave it attached to the circuit, leading to unpredictable
behavior. (Reported by seeess, fixes bug 425.)
svn:r10154
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r-- | src/or/connection_edge.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 3af8044c22..913a9eecf1 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -29,7 +29,8 @@ static smartlist_t *redirect_exit_list = NULL; static int connection_ap_handshake_process_socks(edge_connection_t *conn); static int connection_ap_process_natd(edge_connection_t *conn); -static int connection_exit_connect_dir(edge_connection_t *exit_conn); +static int connection_exit_connect_dir(edge_connection_t *exit_conn, + or_circuit_t *circ); static int hostname_is_noconnect_address(const char *address); /** An AP stream has failed/finished. If it hasn't already sent back @@ -2218,18 +2219,17 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) connection_free(TO_CONN(n_stream)); return 0; } - log_debug(LD_EXIT,"about to start the dns_resolve()."); + + n_stream->on_circuit = circ; if (rh.command == RELAY_COMMAND_BEGIN_DIR) { - if (or_circ && or_circ->p_conn && or_circ->p_conn->_base.addr) + tor_assert(or_circ); + if (or_circ->p_conn && or_circ->p_conn->_base.addr) n_stream->_base.addr = or_circ->p_conn->_base.addr; - n_stream->next_stream = TO_OR_CIRCUIT(circ)->n_streams; - n_stream->on_circuit = circ; - TO_OR_CIRCUIT(circ)->n_streams = n_stream; - return connection_exit_connect_dir(n_stream); + return connection_exit_connect_dir(n_stream, or_circ); } - n_stream->on_circuit = circ; + log_debug(LD_EXIT,"about to start the dns_resolve()."); /* send it off to the gethostbyname farm */ switch (dns_resolve(n_stream)) { @@ -2399,7 +2399,8 @@ connection_exit_connect(edge_connection_t *edge_conn) * DOCDOC no longer uses socketpair */ static int -connection_exit_connect_dir(edge_connection_t *exit_conn) +connection_exit_connect_dir(edge_connection_t *exit_conn, + or_circuit_t *circ) { dir_connection_t *dir_conn = NULL; @@ -2425,6 +2426,9 @@ connection_exit_connect_dir(edge_connection_t *exit_conn) return 0; } + exit_conn->next_stream = circ->n_streams; + circ->n_streams = exit_conn; + if (connection_add(TO_CONN(dir_conn))<0) { connection_edge_end(exit_conn, END_STREAM_REASON_RESOURCELIMIT); connection_close_immediate(TO_CONN(exit_conn)); |