Browse Source

Authorities on IPv6: minor fixes and unit tests

Update the code for IPv6 authorities and fallbacks for function
argument changes.

Update unit tests affected by the function argument changes in
the patch.

Add unit tests for authority and fallback:
 * adding via a function
 * line parsing
 * adding default authorities
(Adding default fallbacks is unit tested in #15775.)
teor (Tim Wilson-Brown) 8 years ago
parent
commit
1c2366ea43
5 changed files with 205 additions and 24 deletions
  1. 5 0
      changes/feature17327
  2. 6 7
      src/or/config.c
  3. 5 3
      src/or/config.h
  4. 175 0
      src/test/test_config.c
  5. 14 14
      src/test/test_dir_handle_get.c

+ 5 - 0
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".

+ 6 - 7
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));

+ 5 - 3
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

+ 175 - 0
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),

+ 14 - 14
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);