Sfoglia il codice sorgente

New config options AuthDirBadDir and AuthDirListBadDirs for
authorities to mark certain relays as "bad directories" in the
networkstatus documents. Also supports the "!baddir" directive in
the approved-routers file.


svn:r12754

Roger Dingledine 18 anni fa
parent
commit
ee6ae92670
7 ha cambiato i file con 67 aggiunte e 10 eliminazioni
  1. 4 0
      ChangeLog
  2. 2 0
      doc/spec/dir-spec.txt
  3. 2 0
      src/or/config.c
  4. 35 9
      src/or/dirserv.c
  5. 1 0
      src/or/networkstatus.c
  6. 8 1
      src/or/or.h
  7. 15 0
      src/or/policies.c

+ 4 - 0
ChangeLog

@@ -67,6 +67,10 @@ Changes in version 0.2.0.13-alpha - 2007-12-??
       addresses.
       addresses.
     - Allow multiple HashedControlPassword config lines, to support
     - Allow multiple HashedControlPassword config lines, to support
       multiple controller passwords.
       multiple controller passwords.
+    - New config options AuthDirBadDir and AuthDirListBadDirs for
+      authorities to mark certain relays as "bad directories" in the
+      networkstatus documents. Also supports the "!baddir" directive in
+      the approved-routers file.
 
 
 
 
 Changes in version 0.2.0.12-alpha - 2007-11-16
 Changes in version 0.2.0.12-alpha - 2007-11-16

+ 2 - 0
doc/spec/dir-spec.txt

@@ -1528,6 +1528,8 @@ $Id$
      - Clients SHOULD NOT download directory information from non-'V2Dir'
      - Clients SHOULD NOT download directory information from non-'V2Dir'
        caches.
        caches.
 
 
+   See the "path-spec.txt" document for more details.
+
 6.2. Managing naming
 6.2. Managing naming
 
 
    In order to provide human-memorable names for individual server
    In order to provide human-memorable names for individual server

+ 2 - 0
src/or/config.c

@@ -131,10 +131,12 @@ static config_var_t _option_vars[] = {
   V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
   V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
   V(AllowNonRFC953Hostnames,     BOOL,     "0"),
   V(AllowNonRFC953Hostnames,     BOOL,     "0"),
   V(AssumeReachable,             BOOL,     "0"),
   V(AssumeReachable,             BOOL,     "0"),
+  V(AuthDirBadDir,               LINELIST, NULL),
   V(AuthDirBadExit,              LINELIST, NULL),
   V(AuthDirBadExit,              LINELIST, NULL),
   V(AuthDirInvalid,              LINELIST, NULL),
   V(AuthDirInvalid,              LINELIST, NULL),
   V(AuthDirReject,               LINELIST, NULL),
   V(AuthDirReject,               LINELIST, NULL),
   V(AuthDirRejectUnlisted,       BOOL,     "0"),
   V(AuthDirRejectUnlisted,       BOOL,     "0"),
+  V(AuthDirListBadDirs,          BOOL,     "0"),
   V(AuthDirListBadExits,         BOOL,     "0"),
   V(AuthDirListBadExits,         BOOL,     "0"),
   VAR("AuthoritativeDirectory",  BOOL, AuthoritativeDir,    "0"),
   VAR("AuthoritativeDirectory",  BOOL, AuthoritativeDir,    "0"),
   V(AutomapHostsOnResolve,       BOOL,     "0"),
   V(AutomapHostsOnResolve,       BOOL,     "0"),

+ 35 - 9
src/or/dirserv.c

@@ -66,8 +66,9 @@ static int dirserv_add_extrainfo(extrainfo_t *ei, const char **msg);
 #define FP_NAMED   1  /**< Listed in fingerprint file. */
 #define FP_NAMED   1  /**< Listed in fingerprint file. */
 #define FP_INVALID 2  /**< Believed invalid. */
 #define FP_INVALID 2  /**< Believed invalid. */
 #define FP_REJECT  4  /**< We will not publish this router. */
 #define FP_REJECT  4  /**< We will not publish this router. */
-#define FP_BADEXIT 8  /**< We'll tell clients not to use this as an exit. */
-#define FP_UNNAMED 16 /**< Another router has this name in fingerprint file. */
+#define FP_BADDIR  8  /**< We'll tell clients to avoid using this as a dir. */
+#define FP_BADEXIT 16  /**< We'll tell clients not to use this as an exit. */
+#define FP_UNNAMED 32 /**< Another router has this name in fingerprint file. */
 
 
 /** Encapsulate a nickname and an FP_* status; target of status_by_digest
 /** Encapsulate a nickname and an FP_* status; target of status_by_digest
  * map. */
  * map. */
@@ -149,6 +150,8 @@ add_fingerprint_to_dir(const char *nickname, const char *fp,
       status->status |= FP_REJECT;
       status->status |= FP_REJECT;
     } else if (!strcasecmp(nickname, "!invalid")) {
     } else if (!strcasecmp(nickname, "!invalid")) {
       status->status |= FP_INVALID;
       status->status |= FP_INVALID;
+    } else if (!strcasecmp(nickname, "!baddir")) {
+      status->status |= FP_BADDIR;
     } else if (!strcasecmp(nickname, "!badexit")) {
     } else if (!strcasecmp(nickname, "!badexit")) {
       status->status |= FP_BADEXIT;
       status->status |= FP_BADEXIT;
     }
     }
@@ -395,6 +398,14 @@ dirserv_get_status_impl(const char *id_digest, const char *nickname,
       *msg = "Fingerprint is marked invalid";
       *msg = "Fingerprint is marked invalid";
   }
   }
 
 
+  if (authdir_policy_baddir_address(addr, or_port)) {
+    if (should_log)
+      log_info(LD_DIRSERV,
+               "Marking '%s' as bad directory because of address '%s'",
+               nickname, address);
+    result |= FP_BADDIR;
+  }
+
   if (authdir_policy_badexit_address(addr, or_port)) {
   if (authdir_policy_badexit_address(addr, or_port)) {
     if (should_log)
     if (should_log)
       log_info(LD_DIRSERV, "Marking '%s' as bad exit because of address '%s'",
       log_info(LD_DIRSERV, "Marking '%s' as bad exit because of address '%s'",
@@ -538,6 +549,7 @@ authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
   /* Okay, looks like we're willing to accept this one. */
   /* Okay, looks like we're willing to accept this one. */
   ri->is_named = (status & FP_NAMED) ? 1 : 0;
   ri->is_named = (status & FP_NAMED) ? 1 : 0;
   ri->is_valid = (status & FP_INVALID) ? 0 : 1;
   ri->is_valid = (status & FP_INVALID) ? 0 : 1;
+  ri->is_bad_directory = (status & FP_BADDIR) ? 1 : 0;
   ri->is_bad_exit = (status & FP_BADEXIT) ? 1 : 0;
   ri->is_bad_exit = (status & FP_BADEXIT) ? 1 : 0;
 
 
   return 0;
   return 0;
@@ -779,6 +791,12 @@ directory_remove_invalid(void)
       ent->is_valid = (r&FP_INVALID)?0:1;
       ent->is_valid = (r&FP_INVALID)?0:1;
       changed = 1;
       changed = 1;
     }
     }
+    if (bool_neq((r & FP_BADDIR), ent->is_bad_directory)) {
+      log_info(LD_DIRSERV, "Router '%s' is now a %s directory", ent->nickname,
+               (r & FP_BADDIR) ? "bad" : "good");
+      ent->is_bad_directory = (r&FP_BADDIR) ? 1: 0;
+      changed = 1;
+    }
     if (bool_neq((r & FP_BADEXIT), ent->is_bad_exit)) {
     if (bool_neq((r & FP_BADEXIT), ent->is_bad_exit)) {
       log_info(LD_DIRSERV, "Router '%s' is now a %s exit", ent->nickname,
       log_info(LD_DIRSERV, "Router '%s' is now a %s exit", ent->nickname,
                (r & FP_BADEXIT) ? "bad" : "good");
                (r & FP_BADEXIT) ? "bad" : "good");
@@ -1849,9 +1867,10 @@ routerstatus_format_entry(char *buf, size_t buf_len,
     return 0;
     return 0;
   cp = buf + strlen(buf);
   cp = buf + strlen(buf);
   r = tor_snprintf(cp, buf_len - (cp-buf),
   r = tor_snprintf(cp, buf_len - (cp-buf),
-                   "s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+                   "s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
                   /* These must stay in alphabetical order. */
                   /* These must stay in alphabetical order. */
                    rs->is_authority?" Authority":"",
                    rs->is_authority?" Authority":"",
+                   rs->is_bad_directory?" BadDirectory":"",
                    rs->is_bad_exit?" BadExit":"",
                    rs->is_bad_exit?" BadExit":"",
                    rs->is_exit?" Exit":"",
                    rs->is_exit?" Exit":"",
                    rs->is_fast?" Fast":"",
                    rs->is_fast?" Fast":"",
@@ -1977,7 +1996,7 @@ static void
 set_routerstatus_from_routerinfo(routerstatus_t *rs,
 set_routerstatus_from_routerinfo(routerstatus_t *rs,
                                  routerinfo_t *ri, time_t now,
                                  routerinfo_t *ri, time_t now,
                                  int naming, int exits_can_be_guards,
                                  int naming, int exits_can_be_guards,
-                                 int listbadexits)
+                                 int listbadexits, int listbaddirs)
 {
 {
   int unstable_version =
   int unstable_version =
     tor_version_as_new_as(ri->platform,"0.1.1.10-alpha") &&
     tor_version_as_new_as(ri->platform,"0.1.1.10-alpha") &&
@@ -2020,6 +2039,7 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
   } else {
   } else {
     rs->is_possible_guard = 0;
     rs->is_possible_guard = 0;
   }
   }
+  rs->is_bad_directory = listbaddirs && ri->is_bad_directory;
   rs->is_bad_exit = listbadexits && ri->is_bad_exit;
   rs->is_bad_exit = listbadexits && ri->is_bad_exit;
   ri->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, now);
   ri->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, now);
   rs->is_hs_dir = ri->is_hs_dir;
   rs->is_hs_dir = ri->is_hs_dir;
@@ -2050,7 +2070,8 @@ clear_status_flags_on_sybil(routerstatus_t *rs)
 {
 {
   rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
   rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
     rs->is_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
     rs->is_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
-    rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit = 0;
+    rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit =
+    rs->is_bad_directory = 0;
   /* FFFF we might want some mechanism to check later on if we
   /* FFFF we might want some mechanism to check later on if we
    * missed zeroing any flags: it's easy to add a new flag but
    * missed zeroing any flags: it's easy to add a new flag but
    * forget to add it to this clause. */
    * forget to add it to this clause. */
@@ -2065,7 +2086,7 @@ router_clear_status_flags(routerinfo_t *router)
   router->is_valid = router->is_running = router->is_hs_dir =
   router->is_valid = router->is_running = router->is_hs_dir =
     router->is_fast = router->is_stable =
     router->is_fast = router->is_stable =
     router->is_possible_guard = router->is_exit =
     router->is_possible_guard = router->is_exit =
-    router->is_bad_exit = 0;
+    router->is_bad_exit = router->is_bad_directory = 0;
 }
 }
 
 
 /** If we've been around for less than this amount of time, our reachability
 /** If we've been around for less than this amount of time, our reachability
@@ -2088,6 +2109,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
   char signing_key_digest[DIGEST_LEN];
   char signing_key_digest[DIGEST_LEN];
   int naming = options->NamingAuthoritativeDir;
   int naming = options->NamingAuthoritativeDir;
   int listbadexits = options->AuthDirListBadExits;
   int listbadexits = options->AuthDirListBadExits;
+  int listbaddirs = options->AuthDirListBadDirs;
   int exits_can_be_guards;
   int exits_can_be_guards;
   routerlist_t *rl = router_get_routerlist();
   routerlist_t *rl = router_get_routerlist();
   time_t now = time(NULL);
   time_t now = time(NULL);
@@ -2157,7 +2179,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
       rs = &vrs->status;
       rs = &vrs->status;
       set_routerstatus_from_routerinfo(rs, ri, now,
       set_routerstatus_from_routerinfo(rs, ri, now,
                                        naming, exits_can_be_guards,
                                        naming, exits_can_be_guards,
-                                       listbadexits);
+                                       listbadexits, listbaddirs);
 
 
       if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
       if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
         clear_status_flags_on_sybil(rs);
         clear_status_flags_on_sybil(rs);
@@ -2211,6 +2233,8 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
                 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
                 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
   if (vote_on_reachability)
   if (vote_on_reachability)
     smartlist_add(v3_out->known_flags, tor_strdup("Running"));
     smartlist_add(v3_out->known_flags, tor_strdup("Running"));
+  if (listbaddirs)
+    smartlist_add(v3_out->known_flags, tor_strdup("BadDirectory"));
   if (listbadexits)
   if (listbadexits)
     smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
     smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
   if (naming) {
   if (naming) {
@@ -2274,6 +2298,7 @@ generate_v2_networkstatus_opinion(void)
   time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
   time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
   int naming = options->NamingAuthoritativeDir;
   int naming = options->NamingAuthoritativeDir;
   int versioning = options->VersioningAuthoritativeDir;
   int versioning = options->VersioningAuthoritativeDir;
+  int listbaddirs = options->AuthDirListBadDirs;
   int listbadexits = options->AuthDirListBadExits;
   int listbadexits = options->AuthDirListBadExits;
   int exits_can_be_guards;
   int exits_can_be_guards;
   const char *contact;
   const char *contact;
@@ -2331,7 +2356,7 @@ generate_v2_networkstatus_opinion(void)
                "fingerprint %s\n"
                "fingerprint %s\n"
                "contact %s\n"
                "contact %s\n"
                "published %s\n"
                "published %s\n"
-               "dir-options%s%s%s\n"
+               "dir-options%s%s%s%s\n"
                "%s" /* client version line, server version line. */
                "%s" /* client version line, server version line. */
                "dir-signing-key\n%s",
                "dir-signing-key\n%s",
                hostname, ipaddr, (int)options->DirPort,
                hostname, ipaddr, (int)options->DirPort,
@@ -2339,6 +2364,7 @@ generate_v2_networkstatus_opinion(void)
                contact,
                contact,
                published,
                published,
                naming ? " Names" : "",
                naming ? " Names" : "",
+               listbaddirs ? " BadDirectories" : "",
                listbadexits ? " BadExits" : "",
                listbadexits ? " BadExits" : "",
                versioning ? " Versions" : "",
                versioning ? " Versions" : "",
                version_lines,
                version_lines,
@@ -2371,7 +2397,7 @@ generate_v2_networkstatus_opinion(void)
 
 
       set_routerstatus_from_routerinfo(&rs, ri, now,
       set_routerstatus_from_routerinfo(&rs, ri, now,
                                        naming, exits_can_be_guards,
                                        naming, exits_can_be_guards,
-                                       listbadexits);
+                                       listbadexits, listbaddirs);
 
 
       if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
       if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
         clear_status_flags_on_sybil(&rs);
         clear_status_flags_on_sybil(&rs);

+ 1 - 0
src/or/networkstatus.c

@@ -1619,6 +1619,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
       router->is_stable = rs->is_stable;
       router->is_stable = rs->is_stable;
       router->is_possible_guard = rs->is_possible_guard;
       router->is_possible_guard = rs->is_possible_guard;
       router->is_exit = rs->is_exit;
       router->is_exit = rs->is_exit;
+      router->is_bad_directory = rs->is_bad_directory;
       router->is_bad_exit = rs->is_bad_exit;
       router->is_bad_exit = rs->is_bad_exit;
       router->is_hs_dir = rs->is_hs_dir;
       router->is_hs_dir = rs->is_hs_dir;
     }
     }

+ 8 - 1
src/or/or.h

@@ -1288,6 +1288,8 @@ typedef struct {
   unsigned int is_exit:1; /**< Do we think this is an OK exit? */
   unsigned int is_exit:1; /**< Do we think this is an OK exit? */
   unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked,
   unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked,
                                * or otherwise nasty? */
                                * or otherwise nasty? */
+  unsigned int is_bad_directory:1; /**< Do we think this directory is junky,
+                                    * underpowered, or otherwise useless? */
   unsigned int wants_to_be_hs_dir:1; /**< True iff this router claims to be
   unsigned int wants_to_be_hs_dir:1; /**< True iff this router claims to be
                                       * a hidden service directory. */
                                       * a hidden service directory. */
   unsigned int is_hs_dir:1; /**< True iff this router is a hidden service
   unsigned int is_hs_dir:1; /**< True iff this router is a hidden service
@@ -2195,12 +2197,16 @@ typedef struct {
   config_line_t *RedirectExit; /**< List of config lines for simple
   config_line_t *RedirectExit; /**< List of config lines for simple
                                        * addr/port redirection */
                                        * addr/port redirection */
   smartlist_t *RedirectExitList; /**< List of exit_redirect_t */
   smartlist_t *RedirectExitList; /**< List of exit_redirect_t */
+  config_line_t *AuthDirBadDir; /**< Address policy for descriptors to
+                                 * mark as bad dir mirrors. */
   config_line_t *AuthDirBadExit; /**< Address policy for descriptors to
   config_line_t *AuthDirBadExit; /**< Address policy for descriptors to
-                                 * mark as bad exits. */
+                                  * mark as bad exits. */
   config_line_t *AuthDirReject; /**< Address policy for descriptors to
   config_line_t *AuthDirReject; /**< Address policy for descriptors to
                                  * reject. */
                                  * reject. */
   config_line_t *AuthDirInvalid; /**< Address policy for descriptors to
   config_line_t *AuthDirInvalid; /**< Address policy for descriptors to
                                   * never mark as valid. */
                                   * never mark as valid. */
+  int AuthDirListBadDirs; /**< True iff we should list bad dirs,
+                           * and vote for all other dir mirrors as good. */
   int AuthDirListBadExits; /**< True iff we should list bad exits,
   int AuthDirListBadExits; /**< True iff we should list bad exits,
                             * and vote for all other exits as good. */
                             * and vote for all other exits as good. */
   int AuthDirRejectUnlisted; /**< Boolean: do we reject all routers that
   int AuthDirRejectUnlisted; /**< Boolean: do we reject all routers that
@@ -3377,6 +3383,7 @@ int dir_policy_permits_address(uint32_t addr);
 int socks_policy_permits_address(uint32_t addr);
 int socks_policy_permits_address(uint32_t addr);
 int authdir_policy_permits_address(uint32_t addr, uint16_t port);
 int authdir_policy_permits_address(uint32_t addr, uint16_t port);
 int authdir_policy_valid_address(uint32_t addr, uint16_t port);
 int authdir_policy_valid_address(uint32_t addr, uint16_t port);
+int authdir_policy_baddir_address(uint32_t addr, uint16_t port);
 int authdir_policy_badexit_address(uint32_t addr, uint16_t port);
 int authdir_policy_badexit_address(uint32_t addr, uint16_t port);
 
 
 int validate_addr_policies(or_options_t *options, char **msg);
 int validate_addr_policies(or_options_t *options, char **msg);

+ 15 - 0
src/or/policies.c

@@ -22,6 +22,9 @@ static addr_policy_t *authdir_reject_policy = NULL;
 /** Policy that addresses for incoming router descriptors must match in order
 /** Policy that addresses for incoming router descriptors must match in order
  * to be marked as valid in our networkstatus. */
  * to be marked as valid in our networkstatus. */
 static addr_policy_t *authdir_invalid_policy = NULL;
 static addr_policy_t *authdir_invalid_policy = NULL;
+/** Policy that addresses for incoming router descriptors must <b>not</b>
+ * match in order to not be marked as BadDirectory. */
+static addr_policy_t *authdir_baddir_policy = NULL;
 /** Policy that addresses for incoming router descriptors must <b>not</b>
 /** Policy that addresses for incoming router descriptors must <b>not</b>
  * match in order to not be marked as BadExit. */
  * match in order to not be marked as BadExit. */
 static addr_policy_t *authdir_badexit_policy = NULL;
 static addr_policy_t *authdir_badexit_policy = NULL;
@@ -206,6 +209,16 @@ authdir_policy_valid_address(uint32_t addr, uint16_t port)
   return addr_policy_permits_address(addr, port, authdir_invalid_policy);
   return addr_policy_permits_address(addr, port, authdir_invalid_policy);
 }
 }
 
 
+/** Return 1 if <b>addr</b>:<b>port</b> should be marked as a bad dir,
+ * based on <b>authdir_baddir_policy</b>. Else return 0.
+ */
+int
+authdir_policy_baddir_address(uint32_t addr, uint16_t port)
+{
+  return ! addr_policy_permits_address(addr, port, authdir_baddir_policy);
+}
+
+
 /** Return 1 if <b>addr</b>:<b>port</b> should be marked as a bad exit,
 /** Return 1 if <b>addr</b>:<b>port</b> should be marked as a bad exit,
  * based on <b>authdir_badexit_policy</b>. Else return 0.
  * based on <b>authdir_badexit_policy</b>. Else return 0.
  */
  */
@@ -289,6 +302,8 @@ policies_parse_from_options(or_options_t *options)
                           &authdir_reject_policy, ADDR_POLICY_REJECT);
                           &authdir_reject_policy, ADDR_POLICY_REJECT);
   load_policy_from_option(options->AuthDirInvalid,
   load_policy_from_option(options->AuthDirInvalid,
                           &authdir_invalid_policy, ADDR_POLICY_REJECT);
                           &authdir_invalid_policy, ADDR_POLICY_REJECT);
+  load_policy_from_option(options->AuthDirBadDir,
+                          &authdir_baddir_policy, ADDR_POLICY_REJECT);
   load_policy_from_option(options->AuthDirBadExit,
   load_policy_from_option(options->AuthDirBadExit,
                           &authdir_badexit_policy, ADDR_POLICY_REJECT);
                           &authdir_badexit_policy, ADDR_POLICY_REJECT);
   parse_reachable_addresses();
   parse_reachable_addresses();