[tor-commits] [tor/master] Add a new ipv6=address:orport flag to DirAuthority and FallbackDir

nickm at torproject.org nickm at torproject.org
Tue Dec 15 18:20:53 UTC 2015


commit 85003f4c80b7c980099fedca7dba0c0a90209084
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Feb 22 16:10:40 2013 -0500

    Add a new ipv6=address:orport flag to DirAuthority and FallbackDir
    
    Resolves # 6027
---
 changes/bug6027     |    4 ++++
 doc/tor.1.txt       |    9 ++++++---
 src/or/config.c     |   32 +++++++++++++++++++++++++++++++-
 src/or/or.h         |    2 ++
 src/or/router.c     |    1 +
 src/or/routerlist.c |   27 ++++++++++++++++++++++++---
 src/or/routerlist.h |    2 ++
 7 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/changes/bug6027 b/changes/bug6027
new file mode 100644
index 0000000..5233876
--- /dev/null
+++ b/changes/bug6027
@@ -0,0 +1,4 @@
+  o Minor features:
+    - Allow users to configure directory authorities and fallback
+      directory servers with IPv6 addresses and ORPorts.  Resolves
+      ticket 6027.
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 041b000..3ef5674 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -358,7 +358,7 @@ GENERAL OPTIONS
     DataDirectory. If the option is set to 1, make the DataDirectory readable
     by the default GID. (Default: 0)
 
-[[FallbackDir]] **FallbackDir** __address__:__port__ orport=__port__ id=__fingerprint__ [weight=__num__]::
+[[FallbackDir]] **FallbackDir** __address__:__port__ orport=__port__ id=__fingerprint__ [weight=__num__] [ipv6=__address__:__orport__]::
     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.
     By default, the directory authorities are also FallbackDirs.
@@ -374,9 +374,12 @@ GENERAL OPTIONS
     "bridge" flag is set. If a flag "orport=**port**" is given, Tor will use the
     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
+    with probability proportional to that weight (default 1.0). If a
     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**. Lastly,
+    if an "ipv6=__address__:__orport__" flag is present, then the directory
+    authority is listening for IPv6 connections on the indicated IPv6 address
+    and OR Port. +
  +
     If no **DirAuthority** line is given, Tor will use the default directory
     authorities. NOTE: this option is intended for setting up a private Tor
diff --git a/src/or/config.c b/src/or/config.c
index 7b42c9f..894bd89 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -5538,6 +5538,7 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
   smartlist_t *items = NULL;
   int r;
   char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
+  tor_addr_port_t ipv6_addrport, *ipv6_addrport_ptr = NULL;
   uint16_t dir_port = 0, or_port = 0;
   char digest[DIGEST_LEN];
   char v3_digest[DIGEST_LEN];
@@ -5594,6 +5595,19 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
       } else {
         type |= V3_DIRINFO|EXTRAINFO_DIRINFO|MICRODESC_DIRINFO;
       }
+    } else if (!strcasecmpstart(flag, "ipv6=")) {
+      if (ipv6_addrport_ptr) {
+        log_warn(LD_CONFIG, "Redundant ipv6 addr/port on DirAuthority line");
+      } else {
+        if (tor_addr_port_parse(LOG_WARN, flag+strlen("ipv6="),
+                                &ipv6_addrport.addr, &ipv6_addrport.port) < 0
+            || tor_addr_family(&ipv6_addrport.addr) != AF_INET6) {
+          log_warn(LD_CONFIG, "Bad ipv6 addr/port %s on DirAuthority line",
+                   escaped(flag));
+          goto err;
+        }
+        ipv6_addrport_ptr = &ipv6_addrport;
+      }
     } else {
       log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirAuthority line",
                flag);
@@ -5636,6 +5650,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,
               address, (int)dir_port, (char*)smartlist_get(items,0));
     if (!(ds = trusted_dir_server_new(nickname, address, dir_port, or_port,
+                                      ipv6_addrport_ptr,
                                       digest, v3_digest, type, weight)))
       goto err;
     dir_server_add(ds);
@@ -5673,6 +5688,7 @@ parse_dir_fallback_line(const char *line,
   int ok;
   char id[DIGEST_LEN];
   char *address=NULL;
+  tor_addr_port_t ipv6_addrport, *ipv6_addrport_ptr = NULL;
   double weight=1.0;
 
   memset(id, 0, sizeof(id));
@@ -5691,6 +5707,19 @@ parse_dir_fallback_line(const char *line,
     } else if (!strcmpstart(cp, "id=")) {
       ok = !base16_decode(id, DIGEST_LEN,
                           cp+strlen("id="), strlen(cp)-strlen("id="));
+    } else if (!strcasecmpstart(cp, "ipv6=")) {
+      if (ipv6_addrport_ptr) {
+        log_warn(LD_CONFIG, "Redundant ipv6 addr/port on FallbackDir line");
+      } else {
+        if (tor_addr_port_parse(LOG_WARN, cp+strlen("ipv6="),
+                                &ipv6_addrport.addr, &ipv6_addrport.port) < 0
+            || tor_addr_family(&ipv6_addrport.addr) != AF_INET6) {
+          log_warn(LD_CONFIG, "Bad ipv6 addr/port %s on FallbackDir line",
+                   escaped(cp));
+          goto end;
+        }
+        ipv6_addrport_ptr = &ipv6_addrport;
+      }
     } else if (!strcmpstart(cp, "weight=")) {
       int ok;
       const char *wstring = cp + strlen("weight=");
@@ -5732,7 +5761,8 @@ parse_dir_fallback_line(const char *line,
 
   if (!validate_only) {
     dir_server_t *ds;
-    ds = fallback_dir_server_new(&addr, dirport, orport, id, weight);
+    ds = fallback_dir_server_new(&addr, dirport, orport, ipv6_addrport_ptr,
+                                 id, weight);
     if (!ds) {
       log_warn(LD_CONFIG, "Couldn't create FallbackDir %s", escaped(line));
       goto end;
diff --git a/src/or/or.h b/src/or/or.h
index 945934e..8fd141b 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -5009,9 +5009,11 @@ typedef struct dir_server_t {
   char *description;
   char *nickname;
   char *address; /**< Hostname. */
+  tor_addr_t ipv6_addr; /**< IPv6 address if present; AF_UNSPEC if not */
   uint32_t addr; /**< IPv4 address. */
   uint16_t dir_port; /**< Directory port. */
   uint16_t or_port; /**< OR port: Used for tunneling connections. */
+  uint16_t ipv6_orport; /**< OR port corresponding to ipv6_addr. */
   double weight; /** Weight used when selecting this node at random */
   char digest[DIGEST_LEN]; /**< Digest of identity key. */
   char v3_identity_digest[DIGEST_LEN]; /**< Digest of v3 (authority only,
diff --git a/src/or/router.c b/src/or/router.c
index bed9dc5..49e2e31 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1026,6 +1026,7 @@ init_keys(void)
     ds = trusted_dir_server_new(options->Nickname, NULL,
                                 router_get_advertised_dir_port(options, 0),
                                 router_get_advertised_or_port(options),
+                                NULL,
                                 digest,
                                 v3_digest,
                                 type, 0.0);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 5e79064..8bded42 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -4043,6 +4043,7 @@ dir_server_new(int is_authority,
                const tor_addr_t *addr,
                const char *hostname,
                uint16_t dir_port, uint16_t or_port,
+               const tor_addr_port_t *addrport_ipv6,
                const char *digest, const char *v3_auth_digest,
                dirinfo_type_t type,
                double weight)
@@ -4059,7 +4060,7 @@ dir_server_new(int is_authority,
   if (tor_addr_family(addr) == AF_INET)
     a = tor_addr_to_ipv4h(addr);
   else
-    return NULL; /*XXXX Support IPv6 */
+    return NULL;
 
   if (!hostname)
     hostname_ = tor_dup_addr(addr);
@@ -4076,6 +4077,18 @@ dir_server_new(int is_authority,
   ent->is_authority = is_authority;
   ent->type = type;
   ent->weight = weight;
+  if (addrport_ipv6) {
+    if (tor_addr_family(&addrport_ipv6->addr) != AF_INET6) {
+      log_warn(LD_BUG, "Hey, I got a non-ipv6 addr as addrport_ipv6.");
+      tor_addr_make_unspec(&ent->ipv6_addr);
+    } else {
+      tor_addr_copy(&ent->ipv6_addr, &addrport_ipv6->addr);
+      ent->ipv6_orport = addrport_ipv6->port;
+    }
+  } else {
+    tor_addr_make_unspec(&ent->ipv6_addr);
+  }
+
   memcpy(ent->digest, digest, DIGEST_LEN);
   if (v3_auth_digest && (type & V3_DIRINFO))
     memcpy(ent->v3_identity_digest, v3_auth_digest, DIGEST_LEN);
@@ -4088,6 +4101,7 @@ dir_server_new(int is_authority,
                  hostname, (int)dir_port);
 
   ent->fake_status.addr = ent->addr;
+  tor_addr_copy(&ent->fake_status.ipv6_addr, &ent->ipv6_addr);
   memcpy(ent->fake_status.identity_digest, digest, DIGEST_LEN);
   if (nickname)
     strlcpy(ent->fake_status.nickname, nickname,
@@ -4096,6 +4110,7 @@ dir_server_new(int is_authority,
     ent->fake_status.nickname[0] = '\0';
   ent->fake_status.dir_port = ent->dir_port;
   ent->fake_status.or_port = ent->or_port;
+  ent->fake_status.ipv6_orport = ent->ipv6_orport;
 
   return ent;
 }
@@ -4107,6 +4122,7 @@ dir_server_new(int is_authority,
 dir_server_t *
 trusted_dir_server_new(const char *nickname, const char *address,
                        uint16_t dir_port, uint16_t or_port,
+                       const tor_addr_port_t *ipv6_addrport,
                        const char *digest, const char *v3_auth_digest,
                        dirinfo_type_t type, double weight)
 {
@@ -4137,7 +4153,9 @@ trusted_dir_server_new(const char *nickname, const char *address,
   tor_addr_from_ipv4h(&addr, a);
 
   result = dir_server_new(1, nickname, &addr, hostname,
-                          dir_port, or_port, digest,
+                          dir_port, or_port,
+                          ipv6_addrport,
+                          digest,
                           v3_auth_digest, type, weight);
   tor_free(hostname);
   return result;
@@ -4149,9 +4167,12 @@ trusted_dir_server_new(const char *nickname, const char *address,
 dir_server_t *
 fallback_dir_server_new(const tor_addr_t *addr,
                         uint16_t dir_port, uint16_t or_port,
+                        const tor_addr_port_t *addrport_ipv6,
                         const char *id_digest, double weight)
 {
-  return dir_server_new(0, NULL, addr, NULL, dir_port, or_port, id_digest,
+  return dir_server_new(0, NULL, addr, NULL, dir_port, or_port,
+                        addrport_ipv6,
+                        id_digest,
                         NULL, ALL_DIRINFO, weight);
 }
 
diff --git a/src/or/routerlist.h b/src/or/routerlist.h
index 100ab58..3c4c9cd 100644
--- a/src/or/routerlist.h
+++ b/src/or/routerlist.h
@@ -170,10 +170,12 @@ int router_exit_policy_rejects_all(const routerinfo_t *router);
 
 dir_server_t *trusted_dir_server_new(const char *nickname, const char *address,
                        uint16_t dir_port, uint16_t or_port,
+                       const tor_addr_port_t *addrport_ipv6,
                        const char *digest, const char *v3_auth_digest,
                        dirinfo_type_t type, double weight);
 dir_server_t *fallback_dir_server_new(const tor_addr_t *addr,
                                       uint16_t dir_port, uint16_t or_port,
+                                      const tor_addr_port_t *addrport_ipv6,
                                       const char *id_digest, double weight);
 void dir_server_add(dir_server_t *ent);
 





More information about the tor-commits mailing list