]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
when we connect to a helper node for the first time, close
authorRoger Dingledine <arma@torproject.org>
Wed, 28 Dec 2005 07:19:55 +0000 (07:19 +0000)
committerRoger Dingledine <arma@torproject.org>
Wed, 28 Dec 2005 07:19:55 +0000 (07:19 +0000)
that connection and its circuits. this lets us go back to
using the old helper nodes rather than immediately using
the last one in the list.

svn:r5670

src/or/circuitbuild.c
src/or/connection_or.c
src/or/or.h

index 7fd39c411df9b11b6643fac221bb069b7c8642f5..da87ca48c895eaa7de1d08545e295cdcdb6d7eb9 100644 (file)
@@ -390,8 +390,8 @@ circuit_handle_first_hop(circuit_t *circ)
   return 0;
 }
 
-/** Find circuits that are waiting on <b>or_conn</b> to become open,
- * if any, and get them to send their create cells forward.
+/** Find any circuits that are waiting on <b>or_conn</b> to become
+ * open and get them to send their create cells forward.
  *
  * Status is 1 if connect succeeded, or 0 if connect failed.
  */
@@ -1927,7 +1927,7 @@ helper_nodes_set_status_from_directory(void)
     changed = 1;
 
   if (changed) {
-    log_fn(severity, LD_CIRC, "    (%d/%d helpers are usable)",
+    log_fn(severity, LD_CIRC, "    (%d/%d helpers are usable/new)",
            num_live_helpers(), smartlist_len(helper_nodes));
     helper_nodes_changed();
   }
@@ -1936,39 +1936,49 @@ helper_nodes_set_status_from_directory(void)
 /** Called when a connection to an OR with the identity digest <b>digest</b>
  * is established (<b>succeeded</b>==1) or has failed (<b>succeeded</b>==0).
  * If the OR is a helper, change that helper's up/down status.
+ * Return 0 normally, or -1 if we want to tear down the new connection.
  */
-void
+int
 helper_node_set_status(const char *digest, int succeeded)
 {
   int changed = 0;
+  int refuse_conn = 0;
 
   if (! helper_nodes)
-    return;
+    return 0;
 
   SMARTLIST_FOREACH(helper_nodes, helper_node_t *, helper,
     {
       if (!memcmp(helper->identity, digest, DIGEST_LEN)) {
         if (succeeded) {
           if (!helper->made_contact) {
+            /* We've just added a new long-term helper node. Perhaps
+             * the network just came back? We should give our earlier
+             * helpers another try too, and close this connection so
+             * we don't use it before we've given the others a shot. */
             helper->made_contact = 1;
-            /* We've just added a new long-term helper node.
-             * Perhaps the network just came back? We should
-             * give our earlier helpers another try too. */
+            refuse_conn = 1;
             SMARTLIST_FOREACH(helper_nodes, helper_node_t *, h,
               {
                 routerinfo_t *r = router_get_by_digest(h->identity);
-                h->down_since = 0;
-                if (r) r->is_running = 1;
+                if (h->made_contact) {
+                  h->down_since = 0;
+                  if (r) r->is_running = 1;
+                }
                 if (h == helper)
                   break;
               });
+            notice(LD_CIRC,
+                   "Connected to new helper node '%s'. Marking earlier "
+                   "helpers up. %d/%d helpers usable/new.", helper->nickname,
+                   num_live_helpers(), smartlist_len(helper_nodes));
             changed = 1;
           }
           if (helper->down_since) {
             /*XXXX shouldn't be so loud. NM */
             notice(LD_CIRC,
                    "Connection to formerly down helper node '%s' succeeded. "
-                   "%d/%d helpers usable.", helper->nickname,
+                   "%d/%d helpers usable/new.", helper->nickname,
                    num_live_helpers(), smartlist_len(helper_nodes));
             helper->down_since = 0;
             changed = 1;
@@ -1977,7 +1987,7 @@ helper_node_set_status(const char *digest, int succeeded)
           if (!helper->made_contact) { /* dump him */
             notice(LD_CIRC,
                    "Connection to never-contacted helper node '%s' failed. "
-                   "Removing from the list. %d/%d helpers usable.",
+                   "Removing from the list. %d/%d helpers usable/new.",
                    helper->nickname,
                    num_live_helpers()-1, smartlist_len(helper_nodes)-1);
             tor_free(helper);
@@ -1986,7 +1996,7 @@ helper_node_set_status(const char *digest, int succeeded)
           } else if (!helper->down_since) {
             helper->down_since = time(NULL);
             warn(LD_CIRC, "Connection to helper node '%s' failed."
-                 " %d/%d helpers usable.",
+                 " %d/%d helpers usable/new.",
                  helper->nickname,
                  num_live_helpers(), smartlist_len(helper_nodes));
             changed = 1;
@@ -1997,6 +2007,7 @@ helper_node_set_status(const char *digest, int succeeded)
 
   if (changed)
     helper_nodes_changed();
+  return refuse_conn ? -1 : 0;
 }
 
 /** Pick a live (up and listed) helper node from the list of helpers, and
index 863595b6fe4536595690abea98272986911aeaab..d7dea976618a94db8d4fcb999c0af8521d07d63f 100644 (file)
@@ -659,12 +659,13 @@ static int
 connection_tls_finish_handshake(connection_t *conn)
 {
   char digest_rcvd[DIGEST_LEN];
+  int started_here = connection_or_nonopen_was_started_here(conn);
 
   debug(LD_OR,"tls handshake done. verifying.");
   if (connection_or_check_valid_handshake(conn, digest_rcvd) < 0)
     return -1;
 
-  if (!connection_or_nonopen_was_started_here(conn)) {
+  if (!started_here) {
 #if 0
     connection_t *c;
     if ((c=connection_or_get_by_identity_digest(digest_rcvd))) {
@@ -683,18 +684,23 @@ connection_tls_finish_handshake(connection_t *conn)
 
   directory_set_dirty();
   conn->state = OR_CONN_STATE_OPEN;
+  control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED);
+  if (started_here) {
+    rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL));
+    if (helper_node_set_status(conn->identity_digest, 1) < 0) {
+      /* pending circs get closed in circuit_about_to_close_connection() */
+      return -1;
+    }
+  }
   connection_watch_events(conn, EV_READ);
   circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */
-  rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL));
-  helper_node_set_status(conn->identity_digest, 1);
-  control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED);
   return 0;
 }
 
 /** Pack <b>cell</b> into wire-format, and write it onto <b>conn</b>'s
  * outbuf.
  *
- * (Commented out) If it's an OR conn, and an entire TLS record is
+ * If it's an OR conn, and an entire TLS record is
  * ready, then try to flush the record now.
  */
 void
index c101ec1a95459c8a32cab2fc4edbbaff33910fa9..4b17094b24593fab70ca132dd5941058405b916f 100644 (file)
@@ -1469,7 +1469,7 @@ void extend_info_free(extend_info_t *info);
 routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
 const char *build_state_get_exit_nickname(cpath_build_state_t *state);
 
-void helper_node_set_status(const char *digest, int succeeded);
+int helper_node_set_status(const char *digest, int succeeded);
 void helper_nodes_set_status_from_directory(void);
 void helper_nodes_update_state(or_state_t *state);
 int helper_nodes_parse_state(or_state_t *state, int set, const char **err);