[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Dirservers now do their own external reachability testing o...



Update of /home2/or/cvsroot/tor/src/or
In directory moria:/home/arma/work/onion/cvs/tor/src/or

Modified Files:
	connection_or.c directory.c dirserv.c main.c or.h router.c 
	routerparse.c 
Log Message:
Dirservers now do their own external reachability testing of each
Tor server, and only list them as running if they've been found to
be reachable.

Dirservers also log trouble servers, but only start complaining loudly
after they've been up for an hour, to reduce false positives. We still
need to do something about the fact that it is quite loud when there
are many trouble servers.


Index: connection_or.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection_or.c,v
retrieving revision 1.184
retrieving revision 1.185
diff -u -d -r1.184 -r1.185
--- connection_or.c	23 Aug 2005 09:50:51 -0000	1.184
+++ connection_or.c	24 Aug 2005 02:31:01 -0000	1.185
@@ -334,15 +334,6 @@
     return NULL;
   }
 
-  /* this function should never be called if we're already connected to
-   * id_digest, but check first to be sure */
-  conn = connection_get_by_identity_digest(id_digest, CONN_TYPE_OR);
-  if (conn) {
-    tor_assert(conn->nickname);
-    log_fn(LOG_WARN,"Asked me to connect to router '%s', but there's already a connection.", conn->nickname);
-    return conn;
-  }
-
   conn = connection_new(CONN_TYPE_OR);
 
   /* set up conn so it's got all the data we need to remember */

Index: directory.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/directory.c,v
retrieving revision 1.244
retrieving revision 1.245
diff -u -d -r1.244 -r1.245
--- directory.c	23 Aug 2005 22:27:17 -0000	1.244
+++ directory.c	24 Aug 2005 02:31:01 -0000	1.245
@@ -807,7 +807,6 @@
       log_fn(LOG_INFO,"updated routers.");
     }
     /* do things we've been waiting to do */
-    helper_nodes_set_status_from_directory();
     directory_has_arrived(time(NULL), conn->identity_digest);
   }
 

Index: dirserv.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.177
retrieving revision 1.178
diff -u -d -r1.177 -r1.178
--- dirserv.c	23 Aug 2005 22:00:35 -0000	1.177
+++ dirserv.c	24 Aug 2005 02:31:01 -0000	1.178
@@ -17,6 +17,8 @@
 /** How many seconds do we wait before regenerating the directory? */
 #define DIR_REGEN_SLACK_TIME 5
 
+extern long stats_n_seconds_working;
+
 /** Do we need to regenerate the directory when someone asks for it? */
 static int the_directory_is_dirty = 1;
 static int runningrouters_is_dirty = 1;
@@ -393,8 +395,9 @@
       *desc = end;
       return verified;
     }
-    /* We don't alrady have a newer one; we'll update this one. */
+    /* We don't already have a newer one; we'll update this one. */
     log_fn(LOG_INFO,"Dirserv updating desc for server %s (nickname '%s')",hex_digest,ri->nickname);
+    ri->last_reachable = ri_old->last_reachable; /* this carries over */
     *msg = verified?"Verified server updated":"Unverified server updated. (Have you sent us your key fingerprint?)";
     routerinfo_free(ri_old);
     smartlist_del_keeporder(descriptor_list, found);
@@ -546,6 +549,9 @@
   return tor_strdup(buf);
 }
 
+#define REACHABLE_TIMEOUT (60*60) /* an hour */
+/* Make sure this is 3 times the value of get_dir_fetch_period() */
+
 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
  * contents of a router-status line, and store it in
  * *<b>router_status_out</b>.  Return 0 on success, -1 on failure.
@@ -556,6 +562,7 @@
   /* List of entries in a router-status style: An optional !, then an optional
    * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
   smartlist_t *rs_entries;
+  time_t now = time(NULL);
   int authdir_mode = get_options()->AuthoritativeDir;
   tor_assert(router_status_out);
 
@@ -563,16 +570,25 @@
 
   SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
   {
-    int is_live;
+    int is_live = 0;
     connection_t *conn;
     conn = connection_get_by_identity_digest(
                     ri->identity_digest, CONN_TYPE_OR);
     if (authdir_mode) {
       /* Treat a router as alive if
        *    - It's me, and I'm not hibernating.
-       * or - we're connected to it. */
-      is_live = (router_is_me(ri) && !we_are_hibernating()) ||
-        (conn && conn->state == OR_CONN_STATE_OPEN);
+       * or - we're connected to it and we've found it reachable recently. */
+      if (router_is_me(ri) && !we_are_hibernating()) {
+        is_live = 1;
+      } else if (conn && conn->state == OR_CONN_STATE_OPEN) {
+        if (now < ri->last_reachable + REACHABLE_TIMEOUT) {
+          is_live = 1;
+        } else {
+          log_fn(stats_n_seconds_working>REACHABLE_TIMEOUT ? LOG_NOTICE : LOG_INFO,
+                 "Router %s (%s:%d) is connected to us but not reachable by us.",
+                 ri->nickname, ri->address, ri->or_port);
+        }
+      }
     } else {
       is_live = ri->is_running;
     }
@@ -982,7 +998,7 @@
                         uint16_t or_port,
                         const char *digest_rcvd,
                         const char *nickname_rcvd,
-                        int as_advertised) //XXXRD
+                        int as_advertised)
 {
   int i;
   tor_assert(address);
@@ -995,10 +1011,9 @@
   for (i = 0; i < smartlist_len(descriptor_list); ++i) {
     routerinfo_t *ri = smartlist_get(descriptor_list, i);
     int drop = 0;
-    if (ri->is_verified)
+    if (strcasecmp(address, ri->address) || or_port != ri->or_port)
       continue;
-    if (!strcasecmp(address, ri->address) &&
-        or_port == ri->or_port) {
+    if (!ri->is_verified) {
       /* We have a router at the same address! */
       if (strcasecmp(ri->nickname, nickname_rcvd)) {
         log_fn(LOG_NOTICE, "Dropping descriptor: nickname '%s' does not match nickname '%s' in cert from %s:%d",
@@ -1009,11 +1024,14 @@
                address, or_port);
         drop = 1;
       }
-      if (drop) {
-        routerinfo_free(ri);
-        smartlist_del(descriptor_list, i--);
-        directory_set_dirty();
-      }
+    }
+    if (drop) {
+      routerinfo_free(ri);
+      smartlist_del(descriptor_list, i--);
+      directory_set_dirty();
+    } else { /* correct nickname and digest. mark this router reachable! */
+      log_fn(LOG_INFO,"Found router %s to be reachable. Yay.", ri->nickname);
+      ri->last_reachable = time(NULL);
     }
   }
 }

Index: main.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/main.c,v
retrieving revision 1.540
retrieving revision 1.541
diff -u -d -r1.540 -r1.541
--- main.c	23 Aug 2005 01:00:30 -0000	1.540
+++ main.c	24 Aug 2005 02:31:02 -0000	1.541
@@ -546,6 +546,9 @@
   if (!time_to_fetch_running_routers)
     time_to_fetch_running_routers = now + get_status_fetch_period(options);
 
+  if (identity_digest) /* if it's fresh */
+    helper_nodes_set_status_from_directory();
+
   if (server_mode(options) && identity_digest) {
     /* if this is us, then our dirport is reachable */
     if (router_digest_is_me(identity_digest))
@@ -554,7 +557,8 @@
 
   if (server_mode(options) &&
       !we_are_hibernating()) { /* connect to the appropriate routers */
-    router_retry_connections();
+    if (!authdir_mode(options))
+      router_retry_connections(0);
     if (identity_digest) /* we got a fresh directory */
       consider_testing_reachability();
   }
@@ -688,13 +692,11 @@
     routerlist_remove_old_routers(ROUTER_MAX_AGE);
 
     if (authdir_mode(options)) {
-      /* We're a directory; dump any old descriptors. */
+      /* Dump any old descriptors. */
       dirserv_remove_old_servers(ROUTER_MAX_AGE);
-    }
-    if (server_mode(options) && !we_are_hibernating()) {
-      /* dirservers try to reconnect, in case connections have failed;
-       * and normal servers try to reconnect to dirservers */
-      router_retry_connections();
+      if (!we_are_hibernating()) { /* try to determine reachability */
+        router_retry_connections(1);
+      }
     }
 
     directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1);
@@ -975,7 +977,7 @@
 
   if (authdir_mode(get_options())) {
     /* the directory is already here, run startup things */
-    router_retry_connections();
+    router_retry_connections(1);
   }
 
   if (server_mode(get_options())) {

Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.649
retrieving revision 1.650
diff -u -d -r1.649 -r1.650
--- or.h	22 Aug 2005 03:10:53 -0000	1.649
+++ or.h	24 Aug 2005 02:31:02 -0000	1.650
@@ -737,6 +737,7 @@
   /* local info */
   int is_running; /**< As far as we know, is this OR currently running? */
   time_t status_set_at; /**< When did we last update is_running? */
+  time_t last_reachable; /**< When was the last time we could reach this OR? */
   int is_verified; /**< Has a trusted dirserver validated this OR? */
 
   smartlist_t *declared_family; /**< Nicknames of router which this router
@@ -1901,7 +1902,7 @@
 int advertised_server_mode(void);
 int proxy_mode(or_options_t *options);
 
-void router_retry_connections(void);
+void router_retry_connections(int force);
 int router_is_clique_mode(routerinfo_t *router);
 void router_upload_dir_desc_to_dirservers(int force);
 void mark_my_descriptor_dirty_if_older_than(time_t when);

Index: router.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/router.c,v
retrieving revision 1.189
retrieving revision 1.190
diff -u -d -r1.189 -r1.190
--- router.c	23 Aug 2005 00:47:44 -0000	1.189
+++ router.c	24 Aug 2005 02:31:02 -0000	1.190
@@ -568,10 +568,13 @@
 
 /** OR only: if in clique mode, try to open connections to all of the
  * other ORs we know about. Otherwise, open connections to those we
- * think are in clique mode.
+ * think are in clique mode.o
+ *
+ * If <b>force</b> is zero, only open the connection if we don't already
+ * have one.
  */
 void
-router_retry_connections(void)
+router_retry_connections(int force)
 {
   int i;
   routerinfo_t *router;
@@ -588,10 +591,12 @@
       continue;
     if (!clique_mode(options) && !router_is_clique_mode(router))
       continue;
-    if (!connection_get_by_identity_digest(router->identity_digest,
+    if (force ||
+        !connection_get_by_identity_digest(router->identity_digest,
                                            CONN_TYPE_OR)) {
-      /* not in the list */
-      log_fn(LOG_DEBUG,"connecting to OR at %s:%u.",router->address,router->or_port);
+      log_fn(LOG_INFO,"%sconnecting to %s at %s:%u.",
+             clique_mode(options) ? "(forced) " : "",
+             router->nickname, router->address, router->or_port);
       connection_or_connect(router->addr, router->or_port, router->identity_digest);
     }
   }

Index: routerparse.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/routerparse.c,v
retrieving revision 1.119
retrieving revision 1.120
diff -u -d -r1.119 -r1.120
--- routerparse.c	16 Aug 2005 02:52:27 -0000	1.119
+++ routerparse.c	24 Aug 2005 02:31:02 -0000	1.120
@@ -738,7 +738,7 @@
     return -1;
   }
   log_fn(LOG_DEBUG,"Signed directory hash starts %s", hex_str(signed_digest,4));
-  if (memcmp(digest, signed_digest, 20)) {
+  if (memcmp(digest, signed_digest, DIGEST_LEN)) {
     log_fn(LOG_WARN, "Error reading directory: signature does not match.");
     return -1;
   }
@@ -992,7 +992,7 @@
     log_fn(LOG_WARN, "Invalid signature %d",t);
     goto err;
   }
-  if (memcmp(digest, signed_digest, 20)) {
+  if (memcmp(digest, signed_digest, DIGEST_LEN)) {
     log_fn(LOG_WARN, "Mismatched signature");
     goto err;
   }