Procházet zdrojové kódy

Raise common code for "detach this stream and try it with a different circuit" into a separate function; make that function handle controller-managed streams right.

svn:r3756
Nick Mathewson před 20 roky
rodič
revize
fd150459b3
4 změnil soubory, kde provedl 32 přidání a 14 odebrání
  1. 1 1
      doc/TODO
  2. 23 6
      src/or/connection_edge.c
  3. 3 1
      src/or/or.h
  4. 5 6
      src/or/relay.c

+ 1 - 1
doc/TODO

@@ -79,7 +79,7 @@ R     - revised circ selection stuff.
         attach them automatically.  ("Hidden" config option.)
       o Implement 'attach stream X to circuit Y' logic.
       - Time out never-attached streams.
-      - If we never get a CONNECTED back, we should put the stream back in
+      o If we never get a CONNECTED back, we should put the stream back in
         CONTROLLER_WAIT, not in CIRCUIT_WAIT.
     - Tests for new controller features
 R o HTTPS proxy for OR CONNECT stuff. (For outgoing SSL connections to

+ 23 - 6
src/or/connection_edge.c

@@ -296,9 +296,6 @@ void connection_ap_expire_beginning(void) {
     connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
     /* un-mark it as ending, since we're going to reuse it */
     conn->has_sent_end = 0;
-    /* move it back into 'pending' state. */
-    conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-    circuit_detach_stream(circ, conn);
     /* kludge to make us not try this circuit again, yet to allow
      * current streams on it to survive if they can: make it
      * unattractive to use for new streams */
@@ -306,8 +303,8 @@ void connection_ap_expire_beginning(void) {
     circ->timestamp_dirty -= options->MaxCircuitDirtiness;
     /* give our stream another 15 seconds to try */
     conn->timestamp_lastread += 15;
-    /* attaching to a dirty circuit is fine */
-    if (connection_ap_handshake_attach_circuit(conn)<0) {
+    /* move it back into 'pending' state, and try to attach. */
+    if (connection_ap_detach_retriable(conn, circ)<0) {
       /* it will never work */
       /* Don't need to send end -- we're not connected */
       conn->has_sent_end = 1;
@@ -342,6 +339,26 @@ void connection_ap_attach_pending(void)
   }
 }
 
+/** DOCDOC
+ * -1 on err, 1 on success, 0 on not-yet-sure.
+ */
+int
+connection_ap_detach_retriable(connection_t *conn, circuit_t *circ)
+{
+  control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE);
+  if (get_options()->ManageConnections) {
+    conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+    circuit_detach_stream(circ,conn);
+    /* Muck with timestamps? */
+    return connection_ap_handshake_attach_circuit(conn);
+  } else {
+    conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
+    circuit_detach_stream(circ,conn);
+    return 0;
+  }
+}
+
+
 /** A client-side struct to remember requests to rewrite addresses
  * to new addresses. These structs make up a tree, with addressmap
  * below as its root.
@@ -839,7 +856,7 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
         return 0;
       }
       rep_hist_note_used_resolve(time(NULL)); /* help predict this next time */
-            control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE);
+      control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE);
     } else { /* socks->command == SOCKS_COMMAND_CONNECT */
       if (socks->port == 0) {
         log_fn(LOG_NOTICE,"Application asked to connect to port 0. Refusing.");

+ 3 - 1
src/or/or.h

@@ -1321,6 +1321,7 @@ int connection_edge_is_rendezvous_stream(connection_t *conn);
 int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit);
 void connection_ap_expire_beginning(void);
 void connection_ap_attach_pending(void);
+int connection_ap_detach_retriable(connection_t *conn, circuit_t *circ);
 
 void addressmap_init(void);
 void addressmap_clean(time_t now);
@@ -1378,7 +1379,8 @@ typedef enum stream_status_event_t {
   STREAM_EVENT_FAILED       = 3,
   STREAM_EVENT_CLOSED       = 4,
   STREAM_EVENT_NEW          = 5,
-  STREAM_EVENT_NEW_RESOLVE  = 6
+  STREAM_EVENT_NEW_RESOLVE  = 6,
+  STREAM_EVENT_FAILED_RETRIABLE = 7
 } stream_status_event_t;
 
 typedef enum or_conn_status_event_t {

+ 5 - 6
src/or/relay.c

@@ -623,10 +623,9 @@ connection_edge_process_relay_cell_not_open(
           router_parse_addr_policy_from_string("reject *:*");
       }
 
-      conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-      circuit_detach_stream(circ,conn);
-      if (connection_ap_handshake_attach_circuit(conn) >= 0)
+      if (connection_ap_detach_retriable(conn, circ) >= 0)
         return 0;
+
       log_fn(LOG_INFO,"Giving up on retrying (from exitpolicy); conn can't be handled.");
       /* else, conn will get closed below */
     } else if (rh->length && reason == END_STREAM_REASON_RESOLVEFAILED) {
@@ -640,14 +639,14 @@ connection_edge_process_relay_cell_not_open(
         log_fn(LOG_INFO,"Resolve of '%s' failed, trying again.",
                conn->socks_request->address);
         circuit_log_path(LOG_INFO,circ);
-        conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-        circuit_detach_stream(circ,conn);
         tor_assert(circ->timestamp_dirty);
         circ->timestamp_dirty -= get_options()->MaxCircuitDirtiness;
         /* make sure not to expire/retry the stream quite yet */
         conn->timestamp_lastread = time(NULL);
-        if (connection_ap_handshake_attach_circuit(conn) >= 0)
+
+        if (connection_ap_detach_retriable(conn, circ) >= 0)
           return 0;
+
         /* else, conn will get closed below */
         log_fn(LOG_INFO,"Giving up on retrying (from resolvefailed); conn can't be handled.");
       } else {