Stop crashing when we're asking to close_if_marked a conn that

hasn't been connection_added yet. This happens when an exit conn
is in dns_wait and we get a relay end cell for it before it finishes.

We were silently leaking each of these marked conns in 0.0.9.x. Now
we actually free them.


svn:r3470
This commit is contained in:
Roger Dingledine 2005-01-30 21:47:47 +00:00
parent 20ecfc757b
commit 3969b6066e

View File

@ -175,14 +175,34 @@ int connection_remove(connection_t *conn) {
return 0; return 0;
} }
/** If it's an edge conn, remove it from the list
* of conn's on this circuit. If it's not on an edge,
* flush and send destroys for all circuits on this conn.
*
* If <b>remove</b> is non-zero, then remove it from the
* connection_array and closeable_connection_lst.
*
* Then free it.
*/
static void connection_unlink(connection_t *conn, int remove) {
circuit_about_to_close_connection(conn);
connection_about_to_close_connection(conn);
if (remove) {
connection_remove(conn);
smartlist_remove(closeable_connection_lst, conn);
}
if (conn->type == CONN_TYPE_EXIT) {
assert_connection_edge_not_dns_pending(conn);
}
connection_free(conn);
}
/** DOCDOC **/ /** DOCDOC **/
void void
add_connection_to_closeable_list(connection_t *conn) add_connection_to_closeable_list(connection_t *conn)
{ {
tor_assert(!smartlist_isin(closeable_connection_lst, conn)); tor_assert(!smartlist_isin(closeable_connection_lst, conn));
tor_assert(conn->marked_for_close); tor_assert(conn->marked_for_close);
tor_assert(conn->poll_index >= 0);
smartlist_add(closeable_connection_lst, conn); smartlist_add(closeable_connection_lst, conn);
} }
@ -287,10 +307,14 @@ close_closeable_connections(void)
for (i = 0; i < smartlist_len(closeable_connection_lst); ) { for (i = 0; i < smartlist_len(closeable_connection_lst); ) {
connection_t *conn = smartlist_get(closeable_connection_lst, i); connection_t *conn = smartlist_get(closeable_connection_lst, i);
if (conn->poll_index < 0) {
connection_unlink(conn, 0); /* blow it away right now */
} else {
if (!conn_close_if_marked(conn->poll_index)) if (!conn_close_if_marked(conn->poll_index))
++i; ++i;
} }
} }
}
/** DOCDOC */ /** DOCDOC */
static void static void
@ -502,18 +526,7 @@ static int conn_close_if_marked(int i) {
conn->marked_for_close); conn->marked_for_close);
} }
} }
/* if it's an edge conn, remove it from the list connection_unlink(conn, 1); /* unlink, remove, free */
* of conn's on this circuit. If it's not on an edge,
* flush and send destroys for all circuits on this conn
*/
circuit_about_to_close_connection(conn);
connection_about_to_close_connection(conn);
connection_remove(conn);
smartlist_remove(closeable_connection_lst, conn);
if (conn->type == CONN_TYPE_EXIT) {
assert_connection_edge_not_dns_pending(conn);
}
connection_free(conn);
return 1; return 1;
} }