be sure to detach streams from the circuit linked list before freeing them

also, don't bother marking a conn for close if you're about to free it


svn:r1935
This commit is contained in:
Roger Dingledine 2004-06-02 18:32:24 +00:00
parent 0932505829
commit 69931106f8
3 changed files with 5 additions and 10 deletions

View file

@ -175,6 +175,8 @@ void connection_free_all(void) {
void connection_about_to_close_connection(connection_t *conn) void connection_about_to_close_connection(connection_t *conn)
{ {
assert(conn->marked_for_close);
if(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT) { if(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT) {
if(!conn->has_sent_end) if(!conn->has_sent_end)
log_fn(LOG_WARN,"Edge connection hasn't sent end yet? Bug."); log_fn(LOG_WARN,"Edge connection hasn't sent end yet? Bug.");

View file

@ -648,7 +648,6 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
if(rend_service_set_connection_addr_port(n_stream, circ) < 0) { if(rend_service_set_connection_addr_port(n_stream, circ) < 0) {
log_fn(LOG_INFO,"Didn't find rendezvous service (port %d)",n_stream->port); log_fn(LOG_INFO,"Didn't find rendezvous service (port %d)",n_stream->port);
connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY, n_stream->cpath_layer); connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY, n_stream->cpath_layer);
connection_mark_for_close(n_stream);
connection_free(n_stream); connection_free(n_stream);
circuit_mark_for_close(circ); /* knock the whole thing down, somebody screwed up */ circuit_mark_for_close(circ); /* knock the whole thing down, somebody screwed up */
return 0; return 0;
@ -683,7 +682,6 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
case -1: /* resolve failed */ case -1: /* resolve failed */
log_fn(LOG_INFO,"Resolve failed (%s).", n_stream->address); log_fn(LOG_INFO,"Resolve failed (%s).", n_stream->address);
connection_edge_end(n_stream, END_STREAM_REASON_RESOLVEFAILED, n_stream->cpath_layer); connection_edge_end(n_stream, END_STREAM_REASON_RESOLVEFAILED, n_stream->cpath_layer);
connection_mark_for_close(n_stream);
connection_free(n_stream); connection_free(n_stream);
break; break;
case 0: /* resolve added to pending list */ case 0: /* resolve added to pending list */
@ -710,7 +708,6 @@ void connection_exit_connect(connection_t *conn) {
router_compare_to_my_exit_policy(conn) == ADDR_POLICY_REJECTED) { router_compare_to_my_exit_policy(conn) == ADDR_POLICY_REJECTED) {
log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port); log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
connection_edge_end(conn, END_STREAM_REASON_EXITPOLICY, conn->cpath_layer); connection_edge_end(conn, END_STREAM_REASON_EXITPOLICY, conn->cpath_layer);
connection_mark_for_close(conn);
circuit_detach_stream(circuit_get_by_conn(conn), conn); circuit_detach_stream(circuit_get_by_conn(conn), conn);
connection_free(conn); connection_free(conn);
return; return;
@ -720,7 +717,6 @@ void connection_exit_connect(connection_t *conn) {
switch(connection_connect(conn, conn->address, conn->addr, conn->port)) { switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
case -1: case -1:
connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED, conn->cpath_layer); connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED, conn->cpath_layer);
connection_mark_for_close(conn);
circuit_detach_stream(circuit_get_by_conn(conn), conn); circuit_detach_stream(circuit_get_by_conn(conn), conn);
connection_free(conn); connection_free(conn);
return; return;

View file

@ -125,7 +125,7 @@ static void purge_expired_resolves(uint32_t now) {
pendconn = pend->conn; pendconn = pend->conn;
connection_edge_end(pendconn, END_STREAM_REASON_MISC, connection_edge_end(pendconn, END_STREAM_REASON_MISC,
pendconn->cpath_layer); pendconn->cpath_layer);
connection_mark_for_close(pendconn); circuit_detach_stream(circuit_get_by_conn(pendconn), pendconn);
connection_free(pendconn); connection_free(pendconn);
tor_free(pend); tor_free(pend);
} }
@ -360,15 +360,13 @@ void dns_cancel_pending_resolve(char *address) {
address); address);
while(resolve->pending_connections) { while(resolve->pending_connections) {
pend = resolve->pending_connections; pend = resolve->pending_connections;
/* So that mark_for_close doesn't double-remove the connection. */
pend->conn->state = EXIT_CONN_STATE_RESOLVEFAILED; pend->conn->state = EXIT_CONN_STATE_RESOLVEFAILED;
pendconn = pend->conn; /* don't pass complex things to the pendconn = pend->conn;
connection_mark_for_close macro */
tor_assert(pendconn->s == -1); tor_assert(pendconn->s == -1);
if(!pendconn->marked_for_close) { if(!pendconn->marked_for_close) {
connection_edge_end(pendconn, END_STREAM_REASON_MISC, pendconn->cpath_layer); connection_edge_end(pendconn, END_STREAM_REASON_MISC, pendconn->cpath_layer);
connection_mark_for_close(pendconn);
} }
circuit_detach_stream(circuit_get_by_conn(pendconn), pendconn);
connection_free(pendconn); connection_free(pendconn);
resolve->pending_connections = pend->next; resolve->pending_connections = pend->next;
tor_free(pend); tor_free(pend);
@ -460,7 +458,6 @@ static void dns_found_answer(char *address, uint32_t addr, char outcome) {
pendconn->state = EXIT_CONN_STATE_RESOLVEFAILED; pendconn->state = EXIT_CONN_STATE_RESOLVEFAILED;
circuit_detach_stream(circuit_get_by_conn(pendconn), pendconn); circuit_detach_stream(circuit_get_by_conn(pendconn), pendconn);
connection_edge_end(pendconn, END_STREAM_REASON_MISC, pendconn->cpath_layer); connection_edge_end(pendconn, END_STREAM_REASON_MISC, pendconn->cpath_layer);
connection_mark_for_close(pendconn);
connection_free(pendconn); connection_free(pendconn);
} else { } else {
/* prevent double-remove. */ /* prevent double-remove. */