[or-cvs] Fix bug 212: Directory authorities should not try to downlo...

Nick Mathewson nickm at seul.org
Tue Dec 6 06:55:45 UTC 2005


Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv11442/src/or

Modified Files:
	dirserv.c or.h routerlist.c 
Log Message:
Fix bug 212: Directory authorities should not try to download server descriptors that they know they will reject.

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.272
retrieving revision 1.273
diff -u -d -r1.272 -r1.273
--- dirserv.c	30 Nov 2005 03:01:16 -0000	1.272
+++ dirserv.c	6 Dec 2005 06:55:43 -0000	1.273
@@ -39,6 +39,12 @@
 static int router_is_general_exit(routerinfo_t *ri);
 static router_status_t dirserv_router_get_status(const routerinfo_t *router,
                                                  const char **msg);
+static router_status_t
+dirserv_get_status_impl(const char *fp, const char *nickname,
+                        const char *address,
+                        uint32_t addr, uint16_t or_port,
+                        const char *platform, const char *contact,
+                        const char **msg, int should_log);
 static int dirserv_thinks_router_is_reachable(routerinfo_t *router,
                                               time_t now);
 
@@ -219,28 +225,67 @@
  * according to our configuration.  Return the appropriate router status.
  *
  * If the status is 'FP_REJECT' and <b>msg</b> is provided, set
- * *<b>msg</b> to an explanation of why.
- */
+ * *<b>msg</b> to an explanation of why. */
 static router_status_t
 dirserv_router_get_status(const routerinfo_t *router, const char **msg)
 {
-  fingerprint_entry_t *nn_ent = NULL, *fp_ent = NULL;
-  char fp[FINGERPRINT_LEN+1];
-
-  if (!fingerprint_list)
-    fingerprint_list = smartlist_create();
+  char fingerprint[FINGERPRINT_LEN+1];
 
-  if (crypto_pk_get_fingerprint(router->identity_pkey, fp, 0)) {
+  if (crypto_pk_get_fingerprint(router->identity_pkey, fingerprint, 0)) {
     warn(LD_BUG,"Error computing fingerprint");
     return -1;
   }
 
-  debug(LD_DIRSERV, "%d fingerprints known.", smartlist_len(fingerprint_list));
+  return dirserv_get_status_impl(fingerprint, router->nickname,
+                                 router->address,
+                                 router->addr, router->or_port,
+                                 router->platform, router->contact_info,
+                                 msg, 1);
+}
+
+/** Return true if there is no point in downloading the router described by
+ * <b>rs</b> because this directory would reject it. */
+int
+dirserv_would_reject_router(routerstatus_t *rs)
+{
+  char fp[FINGERPRINT_LEN+1];
+  router_status_t res;
+  base16_encode(fp, sizeof(fp), rs->identity_digest, DIGEST_LEN);
+
+  res = dirserv_get_status_impl(fp, rs->nickname,
+                                "", /* address is only used in logs */
+                                rs->addr, rs->or_port,
+                                NULL, NULL,
+                                NULL, 0);
+
+  return (res == FP_REJECT);
+}
+
+/** Helper: As dirserv_get_router_status, but takes the router fingerprint
+ * (hex, no spaces), nickname, address (used for logging only), IP address, OR
+ * port, platform (logging only) and contact info (logging only) as arguments.
+ *
+ * If should_log is false, do not log messages.  (There's not much point in
+ * logging that we're rejecting servers we'll not download.)
+ */
+static router_status_t
+dirserv_get_status_impl(const char *fp, const char *nickname,
+                        const char *address,
+                        uint32_t addr, uint16_t or_port,
+                        const char *platform, const char *contact,
+                        const char **msg, int should_log)
+{
+  fingerprint_entry_t *nn_ent = NULL, *fp_ent = NULL;
+  if (!fingerprint_list)
+    fingerprint_list = smartlist_create();
+
+  if (should_log)
+    debug(LD_DIRSERV, "%d fingerprints known.", smartlist_len(fingerprint_list));
   SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t *, ent,
   {
     if (!strcasecmp(fp,ent->fingerprint))
       fp_ent = ent;
-    if (!strcasecmp(router->nickname,ent->nickname))
+    if (!strcasecmp(nickname,ent->nickname))
       nn_ent = ent;
   });
 
@@ -258,37 +303,42 @@
 
   if (!nn_ent) { /* No such server known with that nickname */
     addr_policy_result_t rej = router_compare_addr_to_addr_policy(
-                       router->addr, router->or_port, authdir_reject_policy);
+                       addr, or_port, authdir_reject_policy);
     addr_policy_result_t inv = router_compare_addr_to_addr_policy(
-                       router->addr, router->or_port, authdir_invalid_policy);
+                       addr, or_port, authdir_invalid_policy);
 
     if (rej == ADDR_POLICY_PROBABLY_REJECTED || rej == ADDR_POLICY_REJECTED) {
-      info(LD_DIRSERV, "Rejecting '%s' because of address %s",
-           router->nickname, router->address);
+      if (should_log)
+        info(LD_DIRSERV, "Rejecting '%s' because of address %s",
+             nickname, address);
       if (msg)
         *msg = "Authdir is rejecting routers in this range.";
       return FP_REJECT;
     }
     if (inv == ADDR_POLICY_PROBABLY_REJECTED || inv == ADDR_POLICY_REJECTED) {
-      info(LD_DIRSERV, "Not marking '%s' valid because of address %s",
-           router->nickname, router->address);
+      if (should_log)
+        info(LD_DIRSERV, "Not marking '%s' valid because of address %s",
+             nickname, address);
       return FP_INVALID;
     }
-    if (tor_version_as_new_as(router->platform,"0.1.0.2-rc"))
+    if (!platform || tor_version_as_new_as(platform,"0.1.0.2-rc"))
       return FP_VALID;
     else
       return FP_INVALID;
-    info(LD_DIRSERV,"No fingerprint found for '%s'",router->nickname);
+    if (should_log)
+      info(LD_DIRSERV,"No fingerprint found for '%s'",nickname);
     return 0;
   }
   if (0==strcasecmp(nn_ent->fingerprint, fp)) {
-    debug(LD_DIRSERV,"Good fingerprint for '%s'",router->nickname);
+    if (should_log)
+      debug(LD_DIRSERV,"Good fingerprint for '%s'",nickname);
     return FP_NAMED; /* Right fingerprint. */
   } else {
-    warn(LD_DIRSERV,"Mismatched fingerprint for '%s': expected '%s' got '%s'. ContactInfo '%s', platform '%s'.)",
-         router->nickname, nn_ent->fingerprint, fp,
-         router->contact_info ? router->contact_info : "",
-         router->platform ? router->platform : "");
+    if (should_log)
+      warn(LD_DIRSERV,"Mismatched fingerprint for '%s': expected '%s' got '%s'. ContactInfo '%s', platform '%s'.)",
+           nickname, nn_ent->fingerprint, fp,
+           contact ? contact : "",
+           platform ? platform : "");
     if (msg)
       *msg = "Rejected: There is already a verified server with this nickname and a different fingerprint.";
     return FP_REJECT; /* Wrong fingerprint. */

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.749
retrieving revision 1.750
diff -u -d -r1.749 -r1.750
--- or.h	5 Dec 2005 19:45:54 -0000	1.749
+++ or.h	6 Dec 2005 06:55:43 -0000	1.750
@@ -1820,6 +1820,7 @@
                              int as_advertised);
 int authdir_wants_to_reject_router(routerinfo_t *ri,
                                    const char **msg);
+int dirserv_would_reject_router(routerstatus_t *rs);
 void dirserv_free_all(void);
 
 /********************************* dns.c ***************************/

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.384
retrieving revision 1.385
diff -u -d -r1.384 -r1.385
--- routerlist.c	30 Nov 2005 06:27:59 -0000	1.384
+++ routerlist.c	6 Dec 2005 06:55:43 -0000	1.385
@@ -2953,12 +2953,13 @@
 router_list_downloadable(void)
 {
 #define MAX_OLD_SERVER_DOWNLOAD_RATE 2*60*60
+  or_options_t *options = get_options();
   int n_conns, i, n_downloadable = 0;
   connection_t **carray;
   smartlist_t *superseded = smartlist_create();
   smartlist_t *downloading;
   time_t now = time(NULL);
-  int mirror = server_mode(get_options()) && get_options()->DirPort;
+  int mirror = server_mode(options) && options->DirPort;
   /* these are just used for logging */
   int n_not_ready = 0, n_in_progress = 0, n_uptodate = 0, n_skip_old = 0,
     n_obsolete = 0, xx_n_unrecognized = 0, xx_n_extra_new = 0, xx_n_both = 0,
@@ -2977,8 +2978,13 @@
       rs->should_download = 0;
       ++n_obsolete;
     } if (rs->next_attempt_at < now) {
-      rs->should_download = 1;
-      ++n_downloadable;
+      if (options->AuthoritativeDir &&
+          dirserv_would_reject_router(&rs->status)) {
+        rs->should_download = 0;
+      } else {
+        rs->should_download = 1;
+        ++n_downloadable;
+      }
     } else {
       /*
       char fp[HEX_DIGEST_LEN+1];



More information about the tor-commits mailing list