]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Be more conservative in scanning the list of pending streams
authorNick Mathewson <nickm@torproject.org>
Tue, 17 Nov 2015 13:49:30 +0000 (08:49 -0500)
committerNick Mathewson <nickm@torproject.org>
Tue, 17 Nov 2015 14:04:25 +0000 (09:04 -0500)
Now we only re-scan the list in the cases we did before: when we
have a new circuit that we should try attaching to, or when we have
added a new stream that we haven't tried to attach yet.

This is part of 17590.

src/or/circuituse.c
src/or/connection_edge.c
src/or/connection_edge.h
src/or/main.c
src/or/rendclient.c

index 3a1d1541780531e8a81f4bb8e846faad679523ea..5b244258773cf45785aaa17f96c17eb975da2ddd 100644 (file)
@@ -1475,7 +1475,7 @@ circuit_has_opened(origin_circuit_t *circ)
     case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
       rend_client_rendcirc_has_opened(circ);
       /* Start building an intro circ if we don't have one yet. */
-      connection_ap_attach_pending();
+      connection_ap_attach_pending(1);
       /* This isn't a call to circuit_try_attaching_streams because a
        * circuit in _C_ESTABLISH_REND state isn't connected to its
        * hidden service yet, thus we can't attach streams to it yet,
@@ -1537,14 +1537,14 @@ void
 circuit_try_attaching_streams(origin_circuit_t *circ)
 {
   /* Attach streams to this circuit if we can. */
-  connection_ap_attach_pending();
+  connection_ap_attach_pending(1);
 
   /* The call to circuit_try_clearing_isolation_state here will do
    * nothing and return 0 if we didn't attach any streams to circ
    * above. */
   if (circuit_try_clearing_isolation_state(circ)) {
     /* Maybe *now* we can attach some streams to this circuit. */
-    connection_ap_attach_pending();
+    connection_ap_attach_pending(1);
   }
 }
 
index ce6bacefd330c0491161ea5984bfd4217f0f2871..20a27dc90c7cc3fb0035d11d21a508d2b2d83e0f 100644 (file)
@@ -512,6 +512,8 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn)
 /* XXXXX Free this list on exit. */
 static smartlist_t *pending_entry_connections = NULL;
 
+static int untried_pending_connections = 0;
+
 /** Common code to connection_(ap|exit)_about_to_close. */
 static void
 connection_edge_about_to_close(edge_connection_t *edge_conn)
@@ -766,24 +768,31 @@ connection_ap_rescan_and_attach_pending(void)
                "in pending_entry_connections, but wasn't. No worries; "
                "adding it.",
                pending_entry_connections);
+      untried_pending_connections = 1;
       smartlist_add(pending_entry_connections, entry_conn);
     }
 
   } SMARTLIST_FOREACH_END(conn);
 
-  connection_ap_attach_pending();
+  connection_ap_attach_pending(1);
 }
 
 /** Tell any AP streams that are listed as waiting for a new circuit to try
  * again, either attaching to an available circ or launching a new one.
+ *
+ * If <b>retry</b> is false, only check the list if it contains at least one
+ * streams that we have not yet tried to attach to a circuit.
  */
 void
-connection_ap_attach_pending(void)
+connection_ap_attach_pending(int retry)
 {
   if (PREDICT_UNLIKELY(!pending_entry_connections)) {
     return;
   }
 
+  if (untried_pending_connections == 0 && !retry)
+    return;
+
   SMARTLIST_FOREACH_BEGIN(pending_entry_connections,
                           entry_connection_t *, entry_conn) {
     connection_t *conn = ENTRY_TO_CONN(entry_conn);
@@ -811,6 +820,8 @@ connection_ap_attach_pending(void)
     }
 
   } SMARTLIST_FOREACH_END(entry_conn);
+
+  untried_pending_connections = 0;
 }
 
 /** Mark <b>entry_conn</b> as needing to get attached to a circuit.
@@ -838,6 +849,7 @@ connection_ap_mark_as_pending_circuit(entry_connection_t *entry_conn)
     return;
   }
 
+  untried_pending_connections = 1;
   smartlist_add(pending_entry_connections, entry_conn);
 }
 
index 203099976ff78c105f78b4ce36fd86a75b455c6e..86f3fe990cfcd5bfda3c165fd37a87cb40e93fbf 100644 (file)
@@ -65,7 +65,7 @@ int connection_ap_can_use_exit(const entry_connection_t *conn,
                                const node_t *exit);
 void connection_ap_expire_beginning(void);
 void connection_ap_rescan_and_attach_pending(void);
-void connection_ap_attach_pending(void);
+void connection_ap_attach_pending(int retry);
 void connection_ap_mark_as_pending_circuit(entry_connection_t *entry_conn);
 void connection_ap_fail_onehop(const char *failed_digest,
                                cpath_build_state_t *build_state);
index bfa41b964c0a3745d144fd71b1992e0be0a2af4f..0fe818d74ffdb8d6f968ae25ce9b9898ac57631a 100644 (file)
@@ -2505,10 +2505,10 @@ run_main_loop_once(void)
     }
   }
 
-  /* This should be pretty fast if nothing is pending.  BUT... watch out;
-   * we need to make sure it doesn't show up in the profiles.  five times a
-   * second would be enough, for instance. */
-  connection_ap_attach_pending();
+  /* This will be pretty fast if nothing new is pending. Note that this gets
+   * called once per libevent loop, which will make it happen once per group
+   * of events that fire, or once per second. */
+  connection_ap_attach_pending(0);
 
   return 1;
 }
index 3846ef0c32b0d73df854fbc839c3c5754987f9f3..b8a4b2ab9b6193268094ba45f7ee63adeed9fedd 100644 (file)
@@ -52,7 +52,7 @@ rend_client_introcirc_has_opened(origin_circuit_t *circ)
   tor_assert(circ->cpath);
 
   log_info(LD_REND,"introcirc is open");
-  connection_ap_attach_pending();
+  connection_ap_attach_pending(1);
 }
 
 /** Send the establish-rendezvous cell along a rendezvous circuit. if
@@ -1107,7 +1107,7 @@ rend_client_rendezvous_acked(origin_circuit_t *circ, const uint8_t *request,
    * than trying to attach them all. See comments bug 743. */
   /* If we already have the introduction circuit built, make sure we send
    * the INTRODUCE cell _now_ */
-  connection_ap_attach_pending();
+  connection_ap_attach_pending(1);
   return 0;
 }