Add a new ipv6=address:orport flag to DirAuthority and FallbackDir

Resolves # 6027
This commit is contained in:
Nick Mathewson 2013-02-22 16:10:40 -05:00 committed by teor (Tim Wilson-Brown)
parent f3ed5ec0ca
commit 85003f4c80
7 changed files with 70 additions and 7 deletions

4
changes/bug6027 Normal file
View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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);