mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
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:
parent
20ecfc757b
commit
3969b6066e
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user