]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
New config options AuthDirBadDir and AuthDirListBadDirs for
authorRoger Dingledine <arma@torproject.org>
Mon, 10 Dec 2007 16:49:54 +0000 (16:49 +0000)
committerRoger Dingledine <arma@torproject.org>
Mon, 10 Dec 2007 16:49:54 +0000 (16:49 +0000)
authorities to mark certain relays as "bad directories" in the
networkstatus documents. Also supports the "!baddir" directive in
the approved-routers file.

svn:r12754

ChangeLog
doc/spec/dir-spec.txt
src/or/config.c
src/or/dirserv.c
src/or/networkstatus.c
src/or/or.h
src/or/policies.c

index 963066b32f7b2fa941c469276275dc5027f23801..355b9648044f937bf104019eda5793880aafaa9b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -67,6 +67,10 @@ Changes in version 0.2.0.13-alpha - 2007-12-??
       addresses.
     - Allow multiple HashedControlPassword config lines, to support
       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
index e6ca2cc1e1c6df262932858984067da64627ca4e..8ebc905191e735999d7aa1c475845d0ea81fd477 100644 (file)
@@ -1528,6 +1528,8 @@ $Id$
      - Clients SHOULD NOT download directory information from non-'V2Dir'
        caches.
 
+   See the "path-spec.txt" document for more details.
+
 6.2. Managing naming
 
    In order to provide human-memorable names for individual server
index 9b358fc17e9340d1cbb5a37118ca9b95c853d7a2..81c0fcd9ceb85e050656b83b978454ba76c54cd2 100644 (file)
@@ -131,10 +131,12 @@ static config_var_t _option_vars[] = {
   V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
   V(AllowNonRFC953Hostnames,     BOOL,     "0"),
   V(AssumeReachable,             BOOL,     "0"),
+  V(AuthDirBadDir,               LINELIST, NULL),
   V(AuthDirBadExit,              LINELIST, NULL),
   V(AuthDirInvalid,              LINELIST, NULL),
   V(AuthDirReject,               LINELIST, NULL),
   V(AuthDirRejectUnlisted,       BOOL,     "0"),
+  V(AuthDirListBadDirs,          BOOL,     "0"),
   V(AuthDirListBadExits,         BOOL,     "0"),
   VAR("AuthoritativeDirectory",  BOOL, AuthoritativeDir,    "0"),
   V(AutomapHostsOnResolve,       BOOL,     "0"),
index 2dc87d11a298d3f037d9a9192d928d4177917c97..83cbbf630701d3893e9f5c7b06b1a5cb7e4efffe 100644 (file)
@@ -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_INVALID 2  /**< Believed invalid. */
 #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
  * map. */
@@ -149,6 +150,8 @@ add_fingerprint_to_dir(const char *nickname, const char *fp,
       status->status |= FP_REJECT;
     } else if (!strcasecmp(nickname, "!invalid")) {
       status->status |= FP_INVALID;
+    } else if (!strcasecmp(nickname, "!baddir")) {
+      status->status |= FP_BADDIR;
     } else if (!strcasecmp(nickname, "!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";
   }
 
+  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 (should_log)
       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. */
   ri->is_named = (status & FP_NAMED) ? 1 : 0;
   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;
 
   return 0;
@@ -779,6 +791,12 @@ directory_remove_invalid(void)
       ent->is_valid = (r&FP_INVALID)?0: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)) {
       log_info(LD_DIRSERV, "Router '%s' is now a %s exit", ent->nickname,
                (r & FP_BADEXIT) ? "bad" : "good");
@@ -1849,9 +1867,10 @@ routerstatus_format_entry(char *buf, size_t buf_len,
     return 0;
   cp = buf + strlen(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. */
                    rs->is_authority?" Authority":"",
+                   rs->is_bad_directory?" BadDirectory":"",
                    rs->is_bad_exit?" BadExit":"",
                    rs->is_exit?" Exit":"",
                    rs->is_fast?" Fast":"",
@@ -1977,7 +1996,7 @@ static void
 set_routerstatus_from_routerinfo(routerstatus_t *rs,
                                  routerinfo_t *ri, time_t now,
                                  int naming, int exits_can_be_guards,
-                                 int listbadexits)
+                                 int listbadexits, int listbaddirs)
 {
   int unstable_version =
     tor_version_as_new_as(ri->platform,"0.1.1.10-alpha") &&
@@ -2020,6 +2039,7 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
   } else {
     rs->is_possible_guard = 0;
   }
+  rs->is_bad_directory = listbaddirs && ri->is_bad_directory;
   rs->is_bad_exit = listbadexits && ri->is_bad_exit;
   ri->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, now);
   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_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
    * missed zeroing any flags: it's easy to add a new flag but
    * 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_fast = router->is_stable =
     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
@@ -2088,6 +2109,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
   char signing_key_digest[DIGEST_LEN];
   int naming = options->NamingAuthoritativeDir;
   int listbadexits = options->AuthDirListBadExits;
+  int listbaddirs = options->AuthDirListBadDirs;
   int exits_can_be_guards;
   routerlist_t *rl = router_get_routerlist();
   time_t now = time(NULL);
@@ -2157,7 +2179,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
       rs = &vrs->status;
       set_routerstatus_from_routerinfo(rs, ri, now,
                                        naming, exits_can_be_guards,
-                                       listbadexits);
+                                       listbadexits, listbaddirs);
 
       if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
         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);
   if (vote_on_reachability)
     smartlist_add(v3_out->known_flags, tor_strdup("Running"));
+  if (listbaddirs)
+    smartlist_add(v3_out->known_flags, tor_strdup("BadDirectory"));
   if (listbadexits)
     smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
   if (naming) {
@@ -2274,6 +2298,7 @@ generate_v2_networkstatus_opinion(void)
   time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
   int naming = options->NamingAuthoritativeDir;
   int versioning = options->VersioningAuthoritativeDir;
+  int listbaddirs = options->AuthDirListBadDirs;
   int listbadexits = options->AuthDirListBadExits;
   int exits_can_be_guards;
   const char *contact;
@@ -2331,7 +2356,7 @@ generate_v2_networkstatus_opinion(void)
                "fingerprint %s\n"
                "contact %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. */
                "dir-signing-key\n%s",
                hostname, ipaddr, (int)options->DirPort,
@@ -2339,6 +2364,7 @@ generate_v2_networkstatus_opinion(void)
                contact,
                published,
                naming ? " Names" : "",
+               listbaddirs ? " BadDirectories" : "",
                listbadexits ? " BadExits" : "",
                versioning ? " Versions" : "",
                version_lines,
@@ -2371,7 +2397,7 @@ generate_v2_networkstatus_opinion(void)
 
       set_routerstatus_from_routerinfo(&rs, ri, now,
                                        naming, exits_can_be_guards,
-                                       listbadexits);
+                                       listbadexits, listbaddirs);
 
       if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
         clear_status_flags_on_sybil(&rs);
index 3b4f9d31b02a686112279522c224cac7aa49cb38..6a72340bab1f7f9a9f60fd5617c06be17841563c 100644 (file)
@@ -1619,6 +1619,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
       router->is_stable = rs->is_stable;
       router->is_possible_guard = rs->is_possible_guard;
       router->is_exit = rs->is_exit;
+      router->is_bad_directory = rs->is_bad_directory;
       router->is_bad_exit = rs->is_bad_exit;
       router->is_hs_dir = rs->is_hs_dir;
     }
index 6b29fd714d32863651f0250f254666beebd1a5f4..bf56bdd9ee3e822dc02d3f543e362ce69d8c5c08 100644 (file)
@@ -1288,6 +1288,8 @@ typedef struct {
   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,
                                * 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
                                       * a hidden service directory. */
   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
                                        * addr/port redirection */
   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
-                                 * mark as bad exits. */
+                                  * mark as bad exits. */
   config_line_t *AuthDirReject; /**< Address policy for descriptors to
                                  * reject. */
   config_line_t *AuthDirInvalid; /**< Address policy for descriptors to
                                   * 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,
                             * and vote for all other exits as good. */
   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 authdir_policy_permits_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 validate_addr_policies(or_options_t *options, char **msg);
index 358f766bd5513e2540acb0496594663ce0714be0..4148fa471e2333157bcdf5785d168dbbe5f7f942 100644 (file)
@@ -22,6 +22,9 @@ static addr_policy_t *authdir_reject_policy = NULL;
 /** Policy that addresses for incoming router descriptors must match in order
  * to be marked as valid in our networkstatus. */
 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>
  * match in order to not be marked as BadExit. */
 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 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,
  * 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);
   load_policy_from_option(options->AuthDirInvalid,
                           &authdir_invalid_policy, ADDR_POLICY_REJECT);
+  load_policy_from_option(options->AuthDirBadDir,
+                          &authdir_baddir_policy, ADDR_POLICY_REJECT);
   load_policy_from_option(options->AuthDirBadExit,
                           &authdir_badexit_policy, ADDR_POLICY_REJECT);
   parse_reachable_addresses();