Explorar el Código

Add a way to configure selection weights for dir_server_t

Nick Mathewson hace 12 años
padre
commit
06cd62266f
Se han modificado 2 ficheros con 28 adiciones y 6 borrados
  1. 4 2
      doc/tor.1.txt
  2. 24 4
      src/or/config.c

+ 4 - 2
doc/tor.1.txt

@@ -292,7 +292,7 @@ GENERAL OPTIONS
 **DataDirectory** __DIR__::
 **DataDirectory** __DIR__::
     Store working data in DIR (Default: @LOCALSTATEDIR@/lib/tor)
     Store working data in DIR (Default: @LOCALSTATEDIR@/lib/tor)
 
 
-**FallbackDir** __address__:__port__ orport=__port__ id=__fingerprint__::
+**FallbackDir** __address__:__port__ orport=__port__ id=__fingerprint__ [weight=__num__]::
     When we're unable to connect to any directory cache for directory info
     When we're unable to connect to any directory cache for directory info
     (usually because we don't know about any yet) we try a FallbackDir.
     (usually because we don't know about any yet) we try a FallbackDir.
     By default, the directory authorities are also FallbackDirs.
     By default, the directory authorities are also FallbackDirs.
@@ -310,7 +310,9 @@ GENERAL OPTIONS
     flag is set, or if the "v1" flag is set and the "no-hs" flag is **not** set.
     flag is set, or if the "v1" flag is set and the "no-hs" flag is **not** set.
     Tor will use this authority as a bridge authoritative directory if the
     Tor will use this authority as a bridge authoritative directory if the
     "bridge" flag is set. If a flag "orport=**port**" is given, Tor will use the
     "bridge" flag is set. If a flag "orport=**port**" is given, Tor will use the
-    given port when opening encrypted tunnels to the dirserver. Lastly, if a
+    given port when opening encrypted tunnels to the dirserver. If a flag
+    "weight=**num**" is given, then the directory server is chosen randomly
+    with probability proportional to that weight (default 1.0). Lastly, if a
     flag "v3ident=**fp**" is given, the dirserver is a v3 directory authority
     flag "v3ident=**fp**" is given, the dirserver is a v3 directory authority
     whose v3 long-term signing key has the fingerprint **fp**. +
     whose v3 long-term signing key has the fingerprint **fp**. +
  +
  +

+ 24 - 4
src/or/config.c

@@ -4371,6 +4371,7 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
   char v3_digest[DIGEST_LEN];
   char v3_digest[DIGEST_LEN];
   dirinfo_type_t type = V2_DIRINFO;
   dirinfo_type_t type = V2_DIRINFO;
   int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
   int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
+  double weight = 1.0;
 
 
   items = smartlist_new();
   items = smartlist_new();
   smartlist_split_string(items, line, NULL,
   smartlist_split_string(items, line, NULL,
@@ -4406,6 +4407,14 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
       if (!ok)
       if (!ok)
         log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
         log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
                  portstring);
                  portstring);
+    } else if (!strcmpstart(flag, "weight=")) {
+      int ok;
+      const char *wstring = flag + strlen("weight=");
+      weight = tor_parse_double(wstring, 0, UINT64_MAX, &ok, NULL);
+      if (!ok) {
+        log_warn(LD_CONFIG, "Invalid weight '%s' on DirAuthority line.",flag);
+        weight=1.0;
+      }
     } else if (!strcasecmpstart(flag, "v3ident=")) {
     } else if (!strcasecmpstart(flag, "v3ident=")) {
       char *idstr = flag + strlen("v3ident=");
       char *idstr = flag + strlen("v3ident=");
       if (strlen(idstr) != HEX_DIGEST_LEN ||
       if (strlen(idstr) != HEX_DIGEST_LEN ||
@@ -4469,7 +4478,7 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
     log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
     log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
               address, (int)dir_port, (char*)smartlist_get(items,0));
               address, (int)dir_port, (char*)smartlist_get(items,0));
     if (!(ds = trusted_dir_server_new(nickname, address, dir_port, or_port,
     if (!(ds = trusted_dir_server_new(nickname, address, dir_port, or_port,
-                                      digest, v3_digest, type, 1.0)))
+                                      digest, v3_digest, type, weight)))
       goto err;
       goto err;
     dir_server_add(ds);
     dir_server_add(ds);
   }
   }
@@ -4506,6 +4515,7 @@ parse_dir_fallback_line(const char *line,
   int ok;
   int ok;
   char id[DIGEST_LEN];
   char id[DIGEST_LEN];
   char *address=NULL;
   char *address=NULL;
+  double weight=1.0;
 
 
   memset(id, 0, sizeof(id));
   memset(id, 0, sizeof(id));
   smartlist_split_string(items, line, NULL,
   smartlist_split_string(items, line, NULL,
@@ -4517,12 +4527,22 @@ parse_dir_fallback_line(const char *line,
       smartlist_add(positional, (char*)cp);
       smartlist_add(positional, (char*)cp);
       continue;
       continue;
     }
     }
-    if (!strcmpstart(cp, "orport="))
+    if (!strcmpstart(cp, "orport=")) {
       orport = (int)tor_parse_long(cp+strlen("orport="), 10,
       orport = (int)tor_parse_long(cp+strlen("orport="), 10,
                                    1, 65535, &ok, NULL);
                                    1, 65535, &ok, NULL);
-    else if (!strcmpstart(cp, "id="))
+    } else if (!strcmpstart(cp, "id=")) {
       ok = !base16_decode(id, DIGEST_LEN,
       ok = !base16_decode(id, DIGEST_LEN,
                           cp+strlen("id="), strlen(cp)-strlen("id="));
                           cp+strlen("id="), strlen(cp)-strlen("id="));
+    } else if (!strcmpstart(cp, "weight=")) {
+      int ok;
+      const char *wstring = cp + strlen("weight=");
+      weight = tor_parse_double(wstring, 0, UINT64_MAX, &ok, NULL);
+      if (!ok) {
+        log_warn(LD_CONFIG, "Invalid weight '%s' on FallbackDir line.", cp);
+        weight=1.0;
+      }
+    }
+
     if (!ok) {
     if (!ok) {
       log_warn(LD_CONFIG, "Bad FallbackDir option %s", escaped(cp));
       log_warn(LD_CONFIG, "Bad FallbackDir option %s", escaped(cp));
       goto end;
       goto end;
@@ -4554,7 +4574,7 @@ parse_dir_fallback_line(const char *line,
 
 
   if (!validate_only) {
   if (!validate_only) {
     dir_server_t *ds;
     dir_server_t *ds;
-    ds = fallback_dir_server_new(&addr, dirport, orport, id, 1.0);
+    ds = fallback_dir_server_new(&addr, dirport, orport, id, weight);
     if (!ds) {
     if (!ds) {
       log_warn(LD_CONFIG, "Couldn't create FallbackDir %s", escaped(line));
       log_warn(LD_CONFIG, "Couldn't create FallbackDir %s", escaped(line));
       goto end;
       goto end;