summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/feature173275
-rw-r--r--src/or/config.c13
-rw-r--r--src/or/config.h8
-rw-r--r--src/test/test_config.c175
-rw-r--r--src/test/test_dir_handle_get.c28
5 files changed, 205 insertions, 24 deletions
diff --git a/changes/feature17327 b/changes/feature17327
new file mode 100644
index 0000000000..2fab09990b
--- /dev/null
+++ b/changes/feature17327
@@ -0,0 +1,5 @@
+ o Minor feature (IPv6):
+ - Add a flag ipv6=address:orport to the DirAuthority and FallbackDir torrc
+ options. Add hard-coded ipv6 addresses for directory authorities with
+ ipv6 lines in their descriptors.
+ Closes ticket 17327; patch from Nick Mathewson / "teor".
diff --git a/src/or/config.c b/src/or/config.c
index 894bd893d9..3092a47c02 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -560,9 +560,6 @@ static int options_transition_affects_descriptor(
static int check_nickname_list(char **lst, const char *name, char **msg);
static char *get_bindaddr_from_transport_listen_line(const char *line,
const char *transport);
-static int parse_dir_authority_line(const char *line,
- dirinfo_type_t required_type,
- int validate_only);
static int parse_ports(or_options_t *options, int validate_only,
char **msg_out, int *n_ports_out,
int *world_writable_control_socket);
@@ -897,7 +894,7 @@ static const char *default_authorities[] = {
* but only add them insofar as they share bits with <b>type</b>.
* Each authority's bits are restricted to the bits shared with <b>type</b>.
* If <b>type</b> is ALL_DIRINFO or NO_DIRINFO (zero), add all authorities. */
-static void
+STATIC void
add_default_trusted_dir_authorities(dirinfo_type_t type)
{
int i;
@@ -5531,7 +5528,7 @@ get_options_for_server_transport(const char *transport)
* (minus whatever bits it's missing) as a valid authority.
* Return 0 on success or filtering out by type,
* or -1 if the line isn't well-formed or if we can't add it. */
-static int
+STATIC int
parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
int validate_only)
{
@@ -5600,7 +5597,8 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
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
+ &ipv6_addrport.addr, &ipv6_addrport.port,
+ -1) < 0
|| tor_addr_family(&ipv6_addrport.addr) != AF_INET6) {
log_warn(LD_CONFIG, "Bad ipv6 addr/port %s on DirAuthority line",
escaped(flag));
@@ -5712,7 +5710,8 @@ parse_dir_fallback_line(const char *line,
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
+ &ipv6_addrport.addr, &ipv6_addrport.port,
+ -1) < 0
|| tor_addr_family(&ipv6_addrport.addr) != AF_INET6) {
log_warn(LD_CONFIG, "Bad ipv6 addr/port %s on FallbackDir line",
escaped(cp));
diff --git a/src/or/config.h b/src/or/config.h
index 7e8868804e..bfdd1694eb 100644
--- a/src/or/config.h
+++ b/src/or/config.h
@@ -152,10 +152,12 @@ STATIC int parse_transport_line(const or_options_t *options,
int server);
STATIC int consider_adding_dir_servers(const or_options_t *options,
const or_options_t *old_options);
+STATIC void add_default_trusted_dir_authorities(dirinfo_type_t type);
MOCK_DECL(STATIC void, add_default_fallback_dir_servers, (void));
-STATIC int
-parse_dir_fallback_line(const char *line,
- int validate_only);
+STATIC int parse_dir_authority_line(const char *line,
+ dirinfo_type_t required_type,
+ int validate_only);
+STATIC int parse_dir_fallback_line(const char *line, int validate_only);
#endif
#endif
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 28e9fa0f32..580dae4167 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -1444,6 +1444,176 @@ test_config_resolve_my_address(void *arg)
UNMOCK(tor_gethostname);
}
+static void
+test_config_adding_trusted_dir_server(void *arg)
+{
+ (void)arg;
+
+ const char digest[DIGEST_LEN] = "";
+ dir_server_t *ds = NULL;
+ tor_addr_port_t ipv6;
+ int rv = -1;
+
+ clear_dir_servers();
+ routerlist_free_all();
+
+ /* create a trusted ds without an IPv6 address and port */
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
+ NULL, V3_DIRINFO, 1.0);
+ tt_assert(ds);
+ dir_server_add(ds);
+ tt_assert(get_n_authorities(V3_DIRINFO) == 1);
+ tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 1);
+
+ /* create a trusted ds with an IPv6 address and port */
+ rv = tor_addr_port_parse(LOG_WARN, "[::1]:9061", &ipv6.addr, &ipv6.port, -1);
+ tt_assert(rv == 0);
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, &ipv6, digest,
+ NULL, V3_DIRINFO, 1.0);
+ tt_assert(ds);
+ dir_server_add(ds);
+ tt_assert(get_n_authorities(V3_DIRINFO) == 2);
+ tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 2);
+
+ done:
+ clear_dir_servers();
+ routerlist_free_all();
+}
+
+static void
+test_config_adding_fallback_dir_server(void *arg)
+{
+ (void)arg;
+
+ const char digest[DIGEST_LEN] = "";
+ dir_server_t *ds = NULL;
+ tor_addr_t ipv4;
+ tor_addr_port_t ipv6;
+ int rv = -1;
+
+ clear_dir_servers();
+ routerlist_free_all();
+
+ rv = tor_addr_parse(&ipv4, "127.0.0.1");
+ tt_assert(rv == AF_INET);
+
+ /* create a trusted ds without an IPv6 address and port */
+ ds = fallback_dir_server_new(&ipv4, 9059, 9060, NULL, digest, 1.0);
+ tt_assert(ds);
+ dir_server_add(ds);
+ tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 1);
+
+ /* create a trusted ds with an IPv6 address and port */
+ rv = tor_addr_port_parse(LOG_WARN, "[::1]:9061", &ipv6.addr, &ipv6.port, -1);
+ tt_assert(rv == 0);
+ ds = fallback_dir_server_new(&ipv4, 9059, 9060, &ipv6, digest, 1.0);
+ tt_assert(ds);
+ dir_server_add(ds);
+ tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 2);
+
+ done:
+ clear_dir_servers();
+ routerlist_free_all();
+}
+
+/* No secrets here:
+ * v3ident is `echo "onion" | shasum | cut -d" " -f1 | tr "a-f" "A-F"`
+ * fingerprint is `echo "unionem" | shasum | cut -d" " -f1 | tr "a-f" "A-F"`
+ * with added spaces
+ */
+#define TEST_DIR_AUTH_LINE_START \
+ "foobar orport=12345 " \
+ "v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
+#define TEST_DIR_AUTH_LINE_END \
+ "1.2.3.4:54321 " \
+ "FDB2 FBD2 AAA5 25FA 2999 E617 5091 5A32 C777 3B17"
+#define TEST_DIR_AUTH_IPV6_FLAG \
+ "ipv6=[feed::beef]:9 "
+
+static void
+test_config_parsing_trusted_dir_server(void *arg)
+{
+ (void)arg;
+ int rv = -1;
+
+ /* parse a trusted dir server without an IPv6 address and port */
+ rv = parse_dir_authority_line(TEST_DIR_AUTH_LINE_START
+ TEST_DIR_AUTH_LINE_END,
+ V3_DIRINFO, 1);
+ tt_assert(rv == 0);
+
+ /* parse a trusted dir server with an IPv6 address and port */
+ rv = parse_dir_authority_line(TEST_DIR_AUTH_LINE_START
+ TEST_DIR_AUTH_IPV6_FLAG
+ TEST_DIR_AUTH_LINE_END,
+ V3_DIRINFO, 1);
+ tt_assert(rv == 0);
+
+ /* Since we are only validating, there is no cleanup. */
+ done:
+ ;
+}
+
+#undef TEST_DIR_AUTH_LINE_START
+#undef TEST_DIR_AUTH_LINE_END
+#undef TEST_DIR_AUTH_IPV6_FLAG
+
+/* No secrets here:
+ * id is `echo "syn-propanethial-S-oxide" | shasum | cut -d" " -f1`
+ */
+#define TEST_DIR_FALLBACK_LINE \
+ "1.2.3.4:54321 orport=12345 " \
+ "id=50e643986f31ea1235bcc1af17a1c5c5cfc0ee54 "
+#define TEST_DIR_FALLBACK_IPV6_FLAG \
+ "ipv6=[2015:c0de::deed]:9"
+
+static void
+test_config_parsing_fallback_dir_server(void *arg)
+{
+ (void)arg;
+ int rv = -1;
+
+ /* parse a trusted dir server without an IPv6 address and port */
+ rv = parse_dir_fallback_line(TEST_DIR_FALLBACK_LINE, 1);
+ tt_assert(rv == 0);
+
+ /* parse a trusted dir server with an IPv6 address and port */
+ rv = parse_dir_fallback_line(TEST_DIR_FALLBACK_LINE
+ TEST_DIR_FALLBACK_IPV6_FLAG,
+ 1);
+ tt_assert(rv == 0);
+
+ /* Since we are only validating, there is no cleanup. */
+ done:
+ ;
+}
+
+#undef TEST_DIR_FALLBACK_LINE
+#undef TEST_DIR_FALLBACK_IPV6_FLAG
+
+static void
+test_config_adding_default_trusted_dir_servers(void *arg)
+{
+ (void)arg;
+
+ clear_dir_servers();
+ routerlist_free_all();
+
+ /* Assume we only have one bridge authority */
+ add_default_trusted_dir_authorities(BRIDGE_DIRINFO);
+ tt_assert(get_n_authorities(BRIDGE_DIRINFO) == 1);
+ tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 1);
+
+ /* Assume we have nine V3 authorities */
+ add_default_trusted_dir_authorities(V3_DIRINFO);
+ tt_assert(get_n_authorities(V3_DIRINFO) == 9);
+ tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 10);
+
+ done:
+ clear_dir_servers();
+ routerlist_free_all();
+}
+
static int n_add_default_fallback_dir_servers_known_default = 0;
/**
@@ -3213,6 +3383,11 @@ test_config_adding_dir_servers(void *arg)
{ #name, test_config_ ## name, flags, NULL, NULL }
struct testcase_t config_tests[] = {
+ CONFIG_TEST(adding_trusted_dir_server, TT_FORK),
+ CONFIG_TEST(adding_fallback_dir_server, TT_FORK),
+ CONFIG_TEST(parsing_trusted_dir_server, 0),
+ CONFIG_TEST(parsing_fallback_dir_server, 0),
+ CONFIG_TEST(adding_default_trusted_dir_servers, TT_FORK),
CONFIG_TEST(adding_dir_servers, TT_FORK),
CONFIG_TEST(resolve_my_address, TT_FORK),
CONFIG_TEST(addressmap, 0),
diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c
index be003df2c0..e1ac50e66e 100644
--- a/src/test/test_dir_handle_get.c
+++ b/src/test/test_dir_handle_get.c
@@ -1242,8 +1242,8 @@ test_dir_handle_get_server_keys_all(void* data)
routerlist_free_all();
/* create a trusted ds */
- ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL,
- V3_DIRINFO, 1.0);
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
+ NULL, V3_DIRINFO, 1.0);
tt_assert(ds);
dir_server_add(ds);
@@ -1400,8 +1400,8 @@ test_dir_handle_get_server_keys_fp(void* data)
routerlist_free_all();
/* create a trusted ds */
- ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL,
- V3_DIRINFO, 1.0);
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
+ NULL, V3_DIRINFO, 1.0);
tt_assert(ds);
dir_server_add(ds);
@@ -1554,8 +1554,8 @@ test_dir_handle_get_server_keys_fpsk(void* data)
routerlist_free_all();
/* create a trusted ds */
- ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL,
- V3_DIRINFO, 1.0);
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
+ NULL, V3_DIRINFO, 1.0);
tt_assert(ds);
/* ds v3_identity_digest is the certificate's identity_key */
@@ -1610,8 +1610,8 @@ test_dir_handle_get_server_keys_busy(void* data)
routerlist_free_all();
/* create a trusted ds */
- ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL,
- V3_DIRINFO, 1.0);
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
+ NULL, V3_DIRINFO, 1.0);
tt_assert(ds);
/* ds v3_identity_digest is the certificate's identity_key */
@@ -2005,8 +2005,8 @@ test_dir_handle_get_status_vote_d(void* data)
dirvote_free_all();
/* create a trusted ds */
- ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL,
- V3_DIRINFO, 1.0);
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
+ NULL, V3_DIRINFO, 1.0);
tt_assert(ds);
dir_server_add(ds);
@@ -2353,8 +2353,8 @@ test_dir_handle_get_status_vote_next_authority(void* data)
mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE, NULL);
/* create a trusted ds */
- ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL,
- V3_DIRINFO, 1.0);
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
+ NULL, V3_DIRINFO, 1.0);
tt_assert(ds);
dir_server_add(ds);
@@ -2431,8 +2431,8 @@ test_dir_handle_get_status_vote_current_authority(void* data)
mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE, NULL);
/* create a trusted ds */
- ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL,
- V3_DIRINFO, 1.0);
+ ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
+ NULL, V3_DIRINFO, 1.0);
tt_assert(ds);
dir_server_add(ds);