From 69931106f898aecb60d503d6e10e3aa118961c29 Mon Sep 17 00:00:00 2001
From: Roger Dingledine <arma@torproject.org>
Date: Wed, 2 Jun 2004 18:32:24 +0000
Subject: [PATCH] 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
---
 src/or/connection.c      | 2 ++
 src/or/connection_edge.c | 4 ----
 src/or/dns.c             | 9 +++------
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/src/or/connection.c b/src/or/connection.c
index 90bcd83a3c..b7d2c52e04 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -175,6 +175,8 @@ void connection_free_all(void) {
 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->has_sent_end)
       log_fn(LOG_WARN,"Edge connection hasn't sent end yet? Bug.");
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 3cbd54d154..4f96b14680 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -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) {
       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_mark_for_close(n_stream);
       connection_free(n_stream);
       circuit_mark_for_close(circ); /* knock the whole thing down, somebody screwed up */
       return 0;
@@ -683,7 +682,6 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
     case -1: /* resolve failed */
       log_fn(LOG_INFO,"Resolve failed (%s).", n_stream->address);
       connection_edge_end(n_stream, END_STREAM_REASON_RESOLVEFAILED, n_stream->cpath_layer);
-      connection_mark_for_close(n_stream);
       connection_free(n_stream);
       break;
     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) {
     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_mark_for_close(conn);
     circuit_detach_stream(circuit_get_by_conn(conn), conn);
     connection_free(conn);
     return;
@@ -720,7 +717,6 @@ void connection_exit_connect(connection_t *conn) {
   switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
     case -1:
       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);
       connection_free(conn);
       return;
diff --git a/src/or/dns.c b/src/or/dns.c
index 3809fe7689..a540ade8f2 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -125,7 +125,7 @@ static void purge_expired_resolves(uint32_t now) {
         pendconn = pend->conn;
         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);
         tor_free(pend);
       }
@@ -360,15 +360,13 @@ void dns_cancel_pending_resolve(char *address) {
          address);
   while(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;
-    pendconn = pend->conn; /* don't pass complex things to the
-                              connection_mark_for_close macro */
+    pendconn = pend->conn;
     tor_assert(pendconn->s == -1);
     if(!pendconn->marked_for_close) {
       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);
     resolve->pending_connections = pend->next;
     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;
       circuit_detach_stream(circuit_get_by_conn(pendconn), pendconn);
       connection_edge_end(pendconn, END_STREAM_REASON_MISC, pendconn->cpath_layer);
-      connection_mark_for_close(pendconn);
       connection_free(pendconn);
     } else {
       /* prevent double-remove. */
-- 
GitLab