[tor-commits] [tor/master] Remove all users of addr_port_lookup outside of address.c

nickm at torproject.org nickm at torproject.org
Tue Jul 10 18:48:20 UTC 2018


commit 2f657a1416f2f81dd1be900269c4ae9bdb29f52d
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Jul 10 13:18:55 2018 -0400

    Remove all users of addr_port_lookup outside of address.c
    
    This function has a nasty API, since whether or not it invokes the
    resolver depends on whether one of its arguments is NULL.  That's a
    good way for accidents to happen.
    
    This patch incidentally makes tor-resolve support socks hosts on
    IPv6.
---
 changes/ticket26526_extra |  3 +++
 src/app/config/config.c   | 13 ++--------
 src/lib/net/address.h     |  2 --
 src/test/test_addr.c      | 61 ++---------------------------------------------
 src/tools/tor-gencert.c   | 18 ++++++++------
 src/tools/tor-resolve.c   | 23 +++++++++---------
 6 files changed, 30 insertions(+), 90 deletions(-)

diff --git a/changes/ticket26526_extra b/changes/ticket26526_extra
new file mode 100644
index 000000000..5495962ff
--- /dev/null
+++ b/changes/ticket26526_extra
@@ -0,0 +1,3 @@
+  o Minor features (tor-resolve):
+    - The tor-resolve utility can now be used with IPv6 SOCKS proxies.
+      Side-effect of the refactoring for ticket 26526.
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 665732ea5..fa99fb0c8 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -6459,26 +6459,17 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
   addrport = smartlist_get(items, 0);
   smartlist_del_keeporder(items, 0);
 
-  const char *addrport_sep = strchr(addrport, ':');
-  if (!addrport_sep) {
-    log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s' "
-                        "(':' not found)", addrport);
+  if (tor_addr_port_split(LOG_WARN, addrport, &address, &dir_port) < 0) {
+    log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s'.", addrport);
     goto err;
   }
 
-  address = tor_strndup(addrport, addrport_sep - addrport);
   if (!string_is_valid_ipv4_address(address)) {
     log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s' "
                         "(invalid IPv4 address)", address);
     goto err;
   }
 
-  tor_free(address);
-
-  if (addr_port_lookup(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
-    log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s'", addrport);
-    goto err;
-  }
   if (!dir_port) {
     log_warn(LD_CONFIG, "Missing port in DirAuthority address '%s'",addrport);
     goto err;
diff --git a/src/lib/net/address.h b/src/lib/net/address.h
index f9e533f4a..e857b4068 100644
--- a/src/lib/net/address.h
+++ b/src/lib/net/address.h
@@ -325,8 +325,6 @@ int tor_addr_port_parse(int severity, const char *addrport,
 int tor_addr_hostname_is_local(const char *name);
 
 /* IPv4 helpers */
-int addr_port_lookup(int severity, const char *addrport, char **address,
-                    uint32_t *addr, uint16_t *port_out);
 int parse_port_range(const char *port, uint16_t *port_min_out,
                      uint16_t *port_max_out);
 int addr_mask_get_bits(uint32_t mask);
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index 9ab921c5b..c85779e52 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -15,66 +15,10 @@
 #include <sys/un.h>
 #endif
 
-/** Mocking replacement: only handles localhost. */
-static int
-mock_tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr_out)
-{
-  if (!strcmp(name, "localhost")) {
-    if (family == AF_INET || family == AF_UNSPEC) {
-      tor_addr_from_ipv4h(addr_out, 0x7f000001);
-      return 0;
-    } else if (family == AF_INET6) {
-      char bytes[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
-                         0, 0, 0, 0, 0, 0, 0, 1 };
-      tor_addr_from_ipv6_bytes(addr_out, bytes);
-      return 0;
-    }
-  }
-  return -1;
-}
-
 static void
 test_addr_basic(void *arg)
 {
-  uint32_t u32;
-  uint16_t u16;
-  char *cp;
-
-  /* Test addr_port_lookup */
-  (void)arg;
-  cp = NULL; u32 = 3; u16 = 3;
-  tt_assert(!addr_port_lookup(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
-  tt_str_op(cp,OP_EQ, "1.2.3.4");
-  tt_int_op(u32,OP_EQ, 0x01020304u);
-  tt_int_op(u16,OP_EQ, 0);
-  tor_free(cp);
-  tt_assert(!addr_port_lookup(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
-  tt_str_op(cp,OP_EQ, "4.3.2.1");
-  tt_int_op(u32,OP_EQ, 0x04030201u);
-  tt_int_op(u16,OP_EQ, 99);
-  tor_free(cp);
-
-  MOCK(tor_addr_lookup, mock_tor_addr_lookup);
-
-  tt_assert(!addr_port_lookup(LOG_WARN, "nonexistent.address:4040",
-                               &cp, NULL, &u16));
-  tt_str_op(cp,OP_EQ, "nonexistent.address");
-  tt_int_op(u16,OP_EQ, 4040);
-  tor_free(cp);
-  tt_assert(!addr_port_lookup(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
-  tt_str_op(cp,OP_EQ, "localhost");
-  tt_int_op(u16,OP_EQ, 9999);
-  tt_int_op(u32,OP_EQ, 0x7f000001u);
-  tor_free(cp);
-  u32 = 3;
-  tt_assert(!addr_port_lookup(LOG_WARN, "localhost", NULL, &u32, &u16));
-  tt_ptr_op(cp,OP_EQ, NULL);
-  tt_int_op(u32,OP_EQ, 0x7f000001u);
-  tt_int_op(u16,OP_EQ, 0);
-  tor_free(cp);
-
-  tt_assert(addr_port_lookup(LOG_WARN, "localhost:3", &cp, &u32, NULL));
-  tor_free(cp);
+  (void) arg;
 
   tt_int_op(0,OP_EQ, addr_mask_get_bits(0x0u));
   tt_int_op(32,OP_EQ, addr_mask_get_bits(0xFFFFFFFFu));
@@ -102,8 +46,7 @@ test_addr_basic(void *arg)
   }
 
  done:
-  UNMOCK(tor_addr_lookup);
-  tor_free(cp);
+  ;
 }
 
 #define test_op_ip6_(a,op,b,e1,e2)                               \
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index c1cda0797..efae621d0 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -42,6 +42,7 @@ ENABLE_GCC_WARNING(redundant-decls)
 #include "lib/malloc/util_malloc.h"
 #include "lib/net/address.h"
 #include "lib/net/inaddr.h"
+#include "lib/net/resolve.h"
 #include "lib/string/compat_string.h"
 #include "lib/string/printf.h"
 
@@ -170,19 +171,22 @@ parse_commandline(int argc, char **argv)
     } else if (!strcmp(argv[i], "-v")) {
       verbose = 1;
     } else if (!strcmp(argv[i], "-a")) {
-      uint32_t addr;
+      tor_addr_t addr;
       uint16_t port;
-      char b[INET_NTOA_BUF_LEN];
-      struct in_addr in;
       if (i+1>=argc) {
         fprintf(stderr, "No argument to -a\n");
         return 1;
       }
-      if (addr_port_lookup(LOG_ERR, argv[++i], NULL, &addr, &port)<0)
+      const char *addr_arg = argv[++i];
+      if (tor_addr_port_lookup(addr_arg, &addr, &port)<0) {
+        fprintf(stderr, "Can't resolve address/port for %s", addr_arg);
         return 1;
-      in.s_addr = htonl(addr);
-      tor_inet_ntoa(&in, b, sizeof(b));
-      tor_asprintf(&address, "%s:%d", b, (int)port);
+      }
+      if (tor_addr_family(&addr) != AF_INET) {
+        fprintf(stderr, "%s must resolve to an IPv4 address", addr_arg);
+        return 1;
+      }
+      address = tor_strdup(fmt_addrport(&addr, port));
     } else if (!strcmp(argv[i], "--create-identity-key")) {
       make_new_id = 1;
     } else if (!strcmp(argv[i], "--passphrase-fd")) {
diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c
index 1532d5f20..9358cc8a6 100644
--- a/src/tools/tor-resolve.c
+++ b/src/tools/tor-resolve.c
@@ -197,12 +197,14 @@ socks5_reason_to_string(char reason)
  * address (in host order) into *<b>result_addr</b>.
  */
 static int
-do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
+do_resolve(const char *hostname,
+           const tor_addr_t *sockshost, uint16_t socksport,
            int reverse, int version,
            tor_addr_t *result_addr, char **result_hostname)
 {
   int s = -1;
-  struct sockaddr_in socksaddr;
+  struct sockaddr_storage ss;
+  socklen_t socklen;
   char *req = NULL;
   ssize_t len = 0;
 
@@ -219,11 +221,10 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
     return -1;
   }
 
-  memset(&socksaddr, 0, sizeof(socksaddr));
-  socksaddr.sin_family = AF_INET;
-  socksaddr.sin_port = htons(socksport);
-  socksaddr.sin_addr.s_addr = htonl(sockshost);
-  if (connect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) {
+  socklen = tor_addr_to_sockaddr(sockshost, socksport,
+                                 (struct sockaddr *)&ss, sizeof(ss));
+
+  if (connect(s, (struct sockaddr*)&ss, sizeof(socklen))) {
     log_sock_error("connecting to SOCKS host", s);
     goto err;
   }
@@ -346,7 +347,7 @@ usage(void)
 int
 main(int argc, char **argv)
 {
-  uint32_t sockshost;
+  tor_addr_t sockshost;
   uint16_t socksport = 0, port_option = 0;
   int isSocks4 = 0, isVerbose = 0, isReverse = 0;
   char **arg;
@@ -414,7 +415,7 @@ main(int argc, char **argv)
 
   if (n_args == 1) {
     log_debug(LD_CONFIG, "defaulting to localhost");
-    sockshost = 0x7f000001u; /* localhost */
+    tor_addr_from_ipv4h(&sockshost, 0x7f000001u); /* localhost */
     if (port_option) {
       log_debug(LD_CONFIG, "Using port %d", (int)port_option);
       socksport = port_option;
@@ -423,7 +424,7 @@ main(int argc, char **argv)
       socksport = 9050; /* 9050 */
     }
   } else if (n_args == 2) {
-    if (addr_port_lookup(LOG_WARN, arg[1], NULL, &sockshost, &socksport)<0) {
+    if (tor_addr_port_lookup(arg[1], &sockshost, &socksport)<0) {
       fprintf(stderr, "Couldn't parse/resolve address %s", arg[1]);
       return 1;
     }
@@ -445,7 +446,7 @@ main(int argc, char **argv)
     return 1;
   }
 
-  if (do_resolve(arg[0], sockshost, socksport, isReverse,
+  if (do_resolve(arg[0], &sockshost, socksport, isReverse,
                  isSocks4 ? 4 : 5, &result,
                  &result_hostname))
     return 1;





More information about the tor-commits mailing list