diff --git a/changes/ticket26526_extra b/changes/ticket26526_extra new file mode 100644 index 0000000000..5495962ff7 --- /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 665732ea56..fa99fb0c88 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 f9e533f4a4..e857b4068b 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 9ab921c5b6..c85779e52e 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -15,66 +15,10 @@ #include #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 c1cda07972..efae621d09 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 1532d5f201..9358cc8a6e 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 *result_addr. */ 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;