]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
adding the reattach-after-timeout feature wasn't so easy after all.
authorRoger Dingledine <arma@torproject.org>
Wed, 18 Feb 2004 01:21:20 +0000 (01:21 +0000)
committerRoger Dingledine <arma@torproject.org>
Wed, 18 Feb 2004 01:21:20 +0000 (01:21 +0000)
maybe it works now.

svn:r1101

src/or/circuit.c
src/or/connection_edge.c
src/or/or.h

index 67c79fcbc2714e0c199653054afb664aa762cbe3..4b156bb33274c68c246e1e16f9eaacc78684008c 100644 (file)
@@ -677,13 +677,40 @@ void circuit_close(circuit_t *circ) {
   circuit_free(circ);
 }
 
+void circuit_detach_stream(circuit_t *circ, connection_t *conn) {
+  connection_t *prevconn;
+
+  assert(circ);
+  assert(conn);
+
+  if(conn == circ->p_streams) {
+    circ->p_streams = conn->next_stream;
+    return;
+  }
+  if(conn == circ->n_streams) {
+    circ->n_streams = conn->next_stream;
+    return;
+  }
+  for(prevconn = circ->p_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
+  if(prevconn && prevconn->next_stream) {
+    prevconn->next_stream = conn->next_stream;
+    return;
+  }
+  for(prevconn = circ->n_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
+  if(prevconn && prevconn->next_stream) {
+    prevconn->next_stream = conn->next_stream;
+    return;
+  }
+  log_fn(LOG_ERR,"edge conn not in circuit's list?");
+  assert(0); /* should never get here */
+}
+
 void circuit_about_to_close_connection(connection_t *conn) {
   /* send destroys for all circuits using conn */
   /* currently, we assume it's too late to flush conn's buf here.
    * down the road, maybe we'll consider that eof doesn't mean can't-write
    */
   circuit_t *circ;
-  connection_t *prevconn;
 
   switch(conn->type) {
     case CONN_TYPE_OR:
@@ -714,26 +741,8 @@ void circuit_about_to_close_connection(connection_t *conn) {
           log_fn(LOG_WARN,"1: I called connection_edge_end redundantly.");
       }
 
-      if(conn == circ->p_streams) {
-        circ->p_streams = conn->next_stream;
-        return;
-      }
-      if(conn == circ->n_streams) {
-        circ->n_streams = conn->next_stream;
-        return;
-      }
-      for(prevconn = circ->p_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
-      if(prevconn && prevconn->next_stream) {
-        prevconn->next_stream = conn->next_stream;
-        return;
-      }
-      for(prevconn = circ->n_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
-      if(prevconn && prevconn->next_stream) {
-        prevconn->next_stream = conn->next_stream;
-        return;
-      }
-      log_fn(LOG_ERR,"edge conn not in circuit's list?");
-      assert(0); /* should never get here */
+      circuit_detach_stream(circ, conn);
+
   } /* end switch */
 }
 
index e7fe3aff7c663893c025f198f87a292e7b891690..cb7b2c60bf6e4ff3dc2b24c94b6665046027bb5b 100644 (file)
@@ -10,6 +10,7 @@ extern char *conn_state_to_string[][_CONN_TYPE_MAX+1];
 
 static int connection_ap_handshake_process_socks(connection_t *conn);
 static int connection_ap_handshake_attach_circuit(connection_t *conn);
+static int connection_ap_handshake_attach_circuit_helper(connection_t *conn);
 static void connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ);
 static int connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
                                                int replylen, char success);
@@ -302,16 +303,9 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
         addr = ntohl(*(uint32_t*)(cell->payload+RELAY_HEADER_SIZE+1));
         client_dns_set_entry(conn->socks_request->address, addr);
         conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-        switch(connection_ap_handshake_attach_circuit(conn)) {
-          case -1: /* it will never work */
-            break; /* conn will get closed below */
-          case 0: /* no useful circuits available */
-            if(!circuit_get_newest(conn, 0)) /* is one already on the way? */
-              circuit_launch_new();
-            return 0;
-          case 1: /* it succeeded, great */
-            return 0;
-        }
+        if(connection_ap_handshake_attach_circuit(conn) >= 0)
+          return 0;
+        /* else, conn will get closed below */
       }
 /* XXX add to this log_fn the exit node's nickname? */
       log_fn(LOG_INFO,"end cell (%s) for stream %d. Removing stream.",
@@ -545,6 +539,14 @@ void connection_ap_expire_beginning(void) {
        * reattach to this same circuit, but that's good enough for now.
        */
       conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+      circuit_detach_stream(circuit_get_by_conn(conn), conn);
+      /* give it another 15 seconds to try */
+      conn->timestamp_lastread += 15;
+      if(connection_ap_handshake_attach_circuit(conn)<0) {
+        /* it will never work */
+        conn->marked_for_close = 1;
+        conn->has_sent_end = 1;
+      }
     }
   }
 }
@@ -563,19 +565,10 @@ void connection_ap_attach_pending(void)
     if (conn->type != CONN_TYPE_AP ||
         conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
       continue;
-    switch(connection_ap_handshake_attach_circuit(conn)) {
-      case -1: /* it will never work */
-        conn->marked_for_close = 1;
-        conn->has_sent_end = 1;
-        break;
-      case 0: /* we need to build another circuit */
-        if(!circuit_get_newest(conn, 0)) {
-          /* if there are no acceptable clean or not-very-dirty circs on the way */
-          circuit_launch_new();
-        }
-        break;
-      case 1: /* it succeeded, great */
-        break;
+    if(connection_ap_handshake_attach_circuit(conn) < 0) {
+      /* it will never work */
+      conn->marked_for_close = 1;
+      conn->has_sent_end = 1;
     }
   }
 }
@@ -632,17 +625,22 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
   } /* else socks handshake is done, continue processing */
 
   conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-  switch(connection_ap_handshake_attach_circuit(conn)) {
+  return connection_ap_handshake_attach_circuit(conn);
+}
+
+static int connection_ap_handshake_attach_circuit(connection_t *conn) {
+  /* try attaching. launch new circuit if needed.
+   * return -1 if conn needs to die, else 0. */
+  switch(connection_ap_handshake_attach_circuit_helper(conn)) {
     case -1: /* it will never work */
       return -1;
     case 0: /* no useful circuits available */
       if(!circuit_get_newest(conn, 0)) /* is one already on the way? */
         circuit_launch_new();
-      break;
-    case 1: /* it succeeded, great */
-      break;
+      return 0;
+    default: /* case 1, it succeeded, great */
+      return 0;
   }
-  return 0;
 }
 
 /* Try to find a safe live circuit for CONN_TYPE_AP connection conn. If
@@ -651,7 +649,7 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
  * Otherwise, associate conn with a safe live circuit, start
  * sending a BEGIN cell down the circuit, and return 1.
  */
-static int connection_ap_handshake_attach_circuit(connection_t *conn) {
+static int connection_ap_handshake_attach_circuit_helper(connection_t *conn) {
   circuit_t *circ;
   uint32_t addr;
 
index 1ec9ba6f6986ca24fafa306b06bd3f9b28a55b27..a293e6f0100ee6bc781481347e310539abb2ca11 100644 (file)
@@ -588,6 +588,7 @@ int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type, crypt_pat
 void circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint);
 
 void circuit_close(circuit_t *circ);
+void circuit_detach_stream(circuit_t *circ, connection_t *conn);
 void circuit_about_to_close_connection(connection_t *conn);
 
 void circuit_log_path(int severity, circuit_t *circ);