mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Merge branch 'ticket26526_26532'
This commit is contained in:
commit
422abd4fa3
4
changes/ticket26526
Normal file
4
changes/ticket26526
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
o Code simplification and refactoring:
|
||||||
|
- Utility functions that can perform a DNS lookup are now wholly
|
||||||
|
separated from those that can't, in separate headers and C
|
||||||
|
modules. Closes ticket 26526.
|
3
changes/ticket26526_extra
Normal file
3
changes/ticket26526_extra
Normal file
@ -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.
|
@ -106,6 +106,7 @@
|
|||||||
#include "feature/client/transports.h"
|
#include "feature/client/transports.h"
|
||||||
#include "feature/relay/ext_orport.h"
|
#include "feature/relay/ext_orport.h"
|
||||||
#include "feature/dircommon/voting_schedule.h"
|
#include "feature/dircommon/voting_schedule.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#endif
|
#endif
|
||||||
@ -6459,26 +6460,17 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
|
|||||||
addrport = smartlist_get(items, 0);
|
addrport = smartlist_get(items, 0);
|
||||||
smartlist_del_keeporder(items, 0);
|
smartlist_del_keeporder(items, 0);
|
||||||
|
|
||||||
const char *addrport_sep = strchr(addrport, ':');
|
if (tor_addr_port_split(LOG_WARN, addrport, &address, &dir_port) < 0) {
|
||||||
if (!addrport_sep) {
|
log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s'.", addrport);
|
||||||
log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s' "
|
|
||||||
"(':' not found)", addrport);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
address = tor_strndup(addrport, addrport_sep - addrport);
|
|
||||||
if (!string_is_valid_ipv4_address(address)) {
|
if (!string_is_valid_ipv4_address(address)) {
|
||||||
log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s' "
|
log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s' "
|
||||||
"(invalid IPv4 address)", address);
|
"(invalid IPv4 address)", address);
|
||||||
goto err;
|
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) {
|
if (!dir_port) {
|
||||||
log_warn(LD_CONFIG, "Missing port in DirAuthority address '%s'",addrport);
|
log_warn(LD_CONFIG, "Missing port in DirAuthority address '%s'",addrport);
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "lib/sandbox/sandbox.h"
|
#include "lib/sandbox/sandbox.h"
|
||||||
#include "app/config/statefile.h"
|
#include "app/config/statefile.h"
|
||||||
#include "lib/encoding/confline.h"
|
#include "lib/encoding/confline.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#include "app/config/or_state_st.h"
|
#include "app/config/or_state_st.h"
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@
|
|||||||
#include "lib/sandbox/sandbox.h"
|
#include "lib/sandbox/sandbox.h"
|
||||||
#include "lib/fs/lockfile.h"
|
#include "lib/fs/lockfile.h"
|
||||||
#include "lib/net/buffers_net.h"
|
#include "lib/net/buffers_net.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
#include "lib/tls/tortls.h"
|
#include "lib/tls/tortls.h"
|
||||||
#include "lib/evloop/compat_libevent.h"
|
#include "lib/evloop/compat_libevent.h"
|
||||||
#include "lib/encoding/confline.h"
|
#include "lib/encoding/confline.h"
|
||||||
|
@ -49,9 +49,7 @@
|
|||||||
#include "lib/log/util_bug.h"
|
#include "lib/log/util_bug.h"
|
||||||
#include "lib/malloc/util_malloc.h"
|
#include "lib/malloc/util_malloc.h"
|
||||||
#include "lib/net/address.h"
|
#include "lib/net/address.h"
|
||||||
#include "lib/net/ipv4.h"
|
#include "lib/net/inaddr.h"
|
||||||
#include "lib/net/ipv6.h"
|
|
||||||
#include "lib/net/resolve.h"
|
|
||||||
#include "lib/net/socket.h"
|
#include "lib/net/socket.h"
|
||||||
#include "lib/string/compat_ctype.h"
|
#include "lib/string/compat_ctype.h"
|
||||||
#include "lib/string/compat_string.h"
|
#include "lib/string/compat_string.h"
|
||||||
|
@ -123,6 +123,7 @@
|
|||||||
#include "lib/sandbox/sandbox.h"
|
#include "lib/sandbox/sandbox.h"
|
||||||
#include "feature/nodelist/torcert.h"
|
#include "feature/nodelist/torcert.h"
|
||||||
#include "lib/math/fp.h"
|
#include "lib/math/fp.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#include "feature/dirauth/dirvote.h"
|
#include "feature/dirauth/dirvote.h"
|
||||||
#include "feature/dirauth/mode.h"
|
#include "feature/dirauth/mode.h"
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "feature/nodelist/routerparse.h"
|
#include "feature/nodelist/routerparse.h"
|
||||||
#include "feature/nodelist/routerset.h"
|
#include "feature/nodelist/routerset.h"
|
||||||
#include "lib/encoding/confline.h"
|
#include "lib/encoding/confline.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#include "core/or/cpath_build_state_st.h"
|
#include "core/or/cpath_build_state_st.h"
|
||||||
#include "core/or/crypt_path_st.h"
|
#include "core/or/crypt_path_st.h"
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
/**
|
/**
|
||||||
* \file address.c
|
* \file address.c
|
||||||
* \brief Functions to use and manipulate the tor_addr_t structure.
|
* \brief Functions to use and manipulate the tor_addr_t structure.
|
||||||
|
*
|
||||||
|
* This module doesn't have any support for the libc resolver: that is all in
|
||||||
|
* resolve.c.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#define ADDRESS_PRIVATE
|
#define ADDRESS_PRIVATE
|
||||||
@ -37,13 +40,12 @@
|
|||||||
|
|
||||||
#include "lib/net/address.h"
|
#include "lib/net/address.h"
|
||||||
#include "lib/net/socket.h"
|
#include "lib/net/socket.h"
|
||||||
#include "lib/net/resolve.h"
|
|
||||||
#include "lib/container/smartlist.h"
|
#include "lib/container/smartlist.h"
|
||||||
#include "lib/ctime/di_ops.h"
|
#include "lib/ctime/di_ops.h"
|
||||||
#include "lib/log/torlog.h"
|
#include "lib/log/torlog.h"
|
||||||
#include "lib/log/escape.h"
|
#include "lib/log/escape.h"
|
||||||
#include "lib/malloc/util_malloc.h"
|
#include "lib/malloc/util_malloc.h"
|
||||||
#include "lib/net/ipv4.h"
|
#include "lib/net/inaddr.h"
|
||||||
#include "lib/string/compat_ctype.h"
|
#include "lib/string/compat_ctype.h"
|
||||||
#include "lib/string/compat_string.h"
|
#include "lib/string/compat_string.h"
|
||||||
#include "lib/string/parse_int.h"
|
#include "lib/string/parse_int.h"
|
||||||
@ -234,127 +236,6 @@ tor_addr_make_null(tor_addr_t *a, sa_family_t family)
|
|||||||
a->family = family;
|
a->family = family;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
|
|
||||||
* *<b>addr</b> to the proper IP address and family. The <b>family</b>
|
|
||||||
* argument (which must be AF_INET, AF_INET6, or AF_UNSPEC) declares a
|
|
||||||
* <i>preferred</i> family, though another one may be returned if only one
|
|
||||||
* family is implemented for this address.
|
|
||||||
*
|
|
||||||
* Return 0 on success, -1 on failure; 1 on transient failure.
|
|
||||||
*/
|
|
||||||
MOCK_IMPL(int,
|
|
||||||
tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
|
|
||||||
{
|
|
||||||
/* Perhaps eventually this should be replaced by a tor_getaddrinfo or
|
|
||||||
* something.
|
|
||||||
*/
|
|
||||||
struct in_addr iaddr;
|
|
||||||
struct in6_addr iaddr6;
|
|
||||||
tor_assert(name);
|
|
||||||
tor_assert(addr);
|
|
||||||
tor_assert(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC);
|
|
||||||
if (!*name) {
|
|
||||||
/* Empty address is an error. */
|
|
||||||
return -1;
|
|
||||||
} else if (tor_inet_pton(AF_INET, name, &iaddr)) {
|
|
||||||
/* It's an IPv4 IP. */
|
|
||||||
if (family == AF_INET6)
|
|
||||||
return -1;
|
|
||||||
tor_addr_from_in(addr, &iaddr);
|
|
||||||
return 0;
|
|
||||||
} else if (tor_inet_pton(AF_INET6, name, &iaddr6)) {
|
|
||||||
if (family == AF_INET)
|
|
||||||
return -1;
|
|
||||||
tor_addr_from_in6(addr, &iaddr6);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
#ifdef HAVE_GETADDRINFO
|
|
||||||
int err;
|
|
||||||
struct addrinfo *res=NULL, *res_p;
|
|
||||||
struct addrinfo *best=NULL;
|
|
||||||
struct addrinfo hints;
|
|
||||||
int result = -1;
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = family;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
err = tor_getaddrinfo(name, NULL, &hints, &res);
|
|
||||||
/* The check for 'res' here shouldn't be necessary, but it makes static
|
|
||||||
* analysis tools happy. */
|
|
||||||
if (!err && res) {
|
|
||||||
best = NULL;
|
|
||||||
for (res_p = res; res_p; res_p = res_p->ai_next) {
|
|
||||||
if (family == AF_UNSPEC) {
|
|
||||||
if (res_p->ai_family == AF_INET) {
|
|
||||||
best = res_p;
|
|
||||||
break;
|
|
||||||
} else if (res_p->ai_family == AF_INET6 && !best) {
|
|
||||||
best = res_p;
|
|
||||||
}
|
|
||||||
} else if (family == res_p->ai_family) {
|
|
||||||
best = res_p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!best)
|
|
||||||
best = res;
|
|
||||||
if (best->ai_family == AF_INET) {
|
|
||||||
tor_addr_from_in(addr,
|
|
||||||
&((struct sockaddr_in*)best->ai_addr)->sin_addr);
|
|
||||||
result = 0;
|
|
||||||
} else if (best->ai_family == AF_INET6) {
|
|
||||||
tor_addr_from_in6(addr,
|
|
||||||
&((struct sockaddr_in6*)best->ai_addr)->sin6_addr);
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
tor_freeaddrinfo(res);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return (err == EAI_AGAIN) ? 1 : -1;
|
|
||||||
#else /* !(defined(HAVE_GETADDRINFO)) */
|
|
||||||
struct hostent *ent;
|
|
||||||
int err;
|
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R_6_ARG
|
|
||||||
char buf[2048];
|
|
||||||
struct hostent hostent;
|
|
||||||
int r;
|
|
||||||
r = gethostbyname_r(name, &hostent, buf, sizeof(buf), &ent, &err);
|
|
||||||
#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
|
|
||||||
char buf[2048];
|
|
||||||
struct hostent hostent;
|
|
||||||
ent = gethostbyname_r(name, &hostent, buf, sizeof(buf), &err);
|
|
||||||
#elif defined(HAVE_GETHOSTBYNAME_R_3_ARG)
|
|
||||||
struct hostent_data data;
|
|
||||||
struct hostent hent;
|
|
||||||
memset(&data, 0, sizeof(data));
|
|
||||||
err = gethostbyname_r(name, &hent, &data);
|
|
||||||
ent = err ? NULL : &hent;
|
|
||||||
#else
|
|
||||||
ent = gethostbyname(name);
|
|
||||||
#ifdef _WIN32
|
|
||||||
err = WSAGetLastError();
|
|
||||||
#else
|
|
||||||
err = h_errno;
|
|
||||||
#endif
|
|
||||||
#endif /* defined(HAVE_GETHOSTBYNAME_R_6_ARG) || ... */
|
|
||||||
if (ent) {
|
|
||||||
if (ent->h_addrtype == AF_INET) {
|
|
||||||
tor_addr_from_in(addr, (struct in_addr*) ent->h_addr);
|
|
||||||
} else if (ent->h_addrtype == AF_INET6) {
|
|
||||||
tor_addr_from_in6(addr, (struct in6_addr*) ent->h_addr);
|
|
||||||
} else {
|
|
||||||
tor_assert(0); // LCOV_EXCL_LINE: gethostbyname() returned bizarre type
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
return (err == WSATRY_AGAIN) ? 1 : -1;
|
|
||||||
#else
|
|
||||||
return (err == TRY_AGAIN) ? 1 : -1;
|
|
||||||
#endif
|
|
||||||
#endif /* defined(HAVE_GETADDRINFO) */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return true iff <b>ip</b> is an IP reserved to localhost or local networks
|
/** Return true iff <b>ip</b> is an IP reserved to localhost or local networks
|
||||||
* in RFC1918 or RFC4193 or RFC4291. (fec0::/10, deprecated by RFC3879, is
|
* in RFC1918 or RFC4193 or RFC4291. (fec0::/10, deprecated by RFC3879, is
|
||||||
* also treated as internal for now.)
|
* also treated as internal for now.)
|
||||||
@ -1324,64 +1205,6 @@ tor_addr_parse(tor_addr_t *addr, const char *src)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Parse an address or address-port combination from <b>s</b>, resolve the
|
|
||||||
* address as needed, and put the result in <b>addr_out</b> and (optionally)
|
|
||||||
* <b>port_out</b>. Return 0 on success, negative on failure. */
|
|
||||||
int
|
|
||||||
tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
|
|
||||||
{
|
|
||||||
const char *port;
|
|
||||||
tor_addr_t addr;
|
|
||||||
uint16_t portval;
|
|
||||||
char *tmp = NULL;
|
|
||||||
|
|
||||||
tor_assert(s);
|
|
||||||
tor_assert(addr_out);
|
|
||||||
|
|
||||||
s = eat_whitespace(s);
|
|
||||||
|
|
||||||
if (*s == '[') {
|
|
||||||
port = strstr(s, "]");
|
|
||||||
if (!port)
|
|
||||||
goto err;
|
|
||||||
tmp = tor_strndup(s+1, port-(s+1));
|
|
||||||
port = port+1;
|
|
||||||
if (*port == ':')
|
|
||||||
port++;
|
|
||||||
else
|
|
||||||
port = NULL;
|
|
||||||
} else {
|
|
||||||
port = strchr(s, ':');
|
|
||||||
if (port)
|
|
||||||
tmp = tor_strndup(s, port-s);
|
|
||||||
else
|
|
||||||
tmp = tor_strdup(s);
|
|
||||||
if (port)
|
|
||||||
++port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tor_addr_lookup(tmp, AF_UNSPEC, &addr) != 0)
|
|
||||||
goto err;
|
|
||||||
tor_free(tmp);
|
|
||||||
|
|
||||||
if (port) {
|
|
||||||
portval = (int) tor_parse_long(port, 10, 1, 65535, NULL, NULL);
|
|
||||||
if (!portval)
|
|
||||||
goto err;
|
|
||||||
} else {
|
|
||||||
portval = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port_out)
|
|
||||||
*port_out = portval;
|
|
||||||
tor_addr_copy(addr_out, &addr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
err:
|
|
||||||
tor_free(tmp);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
|
typedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
|
||||||
ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
|
ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
|
||||||
@ -1927,7 +1750,7 @@ tor_addr_port_split(int severity, const char *addrport,
|
|||||||
tor_assert(addrport);
|
tor_assert(addrport);
|
||||||
tor_assert(address_out);
|
tor_assert(address_out);
|
||||||
tor_assert(port_out);
|
tor_assert(port_out);
|
||||||
/* We need to check for IPv6 manually because addr_port_lookup() doesn't
|
/* We need to check for IPv6 manually because the logic below doesn't
|
||||||
* do a good job on IPv6 addresses that lack a port. */
|
* do a good job on IPv6 addresses that lack a port. */
|
||||||
if (tor_addr_parse(&a_tmp, addrport) == AF_INET6) {
|
if (tor_addr_parse(&a_tmp, addrport) == AF_INET6) {
|
||||||
*port_out = 0;
|
*port_out = 0;
|
||||||
@ -1935,30 +1758,11 @@ tor_addr_port_split(int severity, const char *addrport,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return addr_port_lookup(severity, addrport, address_out, NULL, port_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Parse a string of the form "host[:port]" from <b>addrport</b>. If
|
|
||||||
* <b>address</b> is provided, set *<b>address</b> to a copy of the
|
|
||||||
* host portion of the string. If <b>addr</b> is provided, try to
|
|
||||||
* resolve the host portion of the string and store it into
|
|
||||||
* *<b>addr</b> (in host byte order). If <b>port_out</b> is provided,
|
|
||||||
* store the port number into *<b>port_out</b>, or 0 if no port is given.
|
|
||||||
* If <b>port_out</b> is NULL, then there must be no port number in
|
|
||||||
* <b>addrport</b>.
|
|
||||||
* Return 0 on success, -1 on failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
addr_port_lookup(int severity, const char *addrport, char **address,
|
|
||||||
uint32_t *addr, uint16_t *port_out)
|
|
||||||
{
|
|
||||||
const char *colon;
|
const char *colon;
|
||||||
char *address_ = NULL;
|
char *address_ = NULL;
|
||||||
int port_;
|
int port_;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
|
||||||
tor_assert(addrport);
|
|
||||||
|
|
||||||
colon = strrchr(addrport, ':');
|
colon = strrchr(addrport, ':');
|
||||||
if (colon) {
|
if (colon) {
|
||||||
address_ = tor_strndup(addrport, colon-addrport);
|
address_ = tor_strndup(addrport, colon-addrport);
|
||||||
@ -1980,22 +1784,13 @@ addr_port_lookup(int severity, const char *addrport, char **address,
|
|||||||
port_ = 0;
|
port_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr) {
|
if (ok) {
|
||||||
/* There's an addr pointer, so we need to resolve the hostname. */
|
*address_out = address_;
|
||||||
if (tor_lookup_hostname(address_,addr)) {
|
|
||||||
log_fn(severity, LD_NET, "Couldn't look up %s", escaped(address_));
|
|
||||||
ok = 0;
|
|
||||||
*addr = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (address && ok) {
|
|
||||||
*address = address_;
|
|
||||||
} else {
|
} else {
|
||||||
if (address)
|
*address_out = NULL;
|
||||||
*address = NULL;
|
|
||||||
tor_free(address_);
|
tor_free(address_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port_out)
|
if (port_out)
|
||||||
*port_out = ok ? ((uint16_t) port_) : 0;
|
*port_out = ok ? ((uint16_t) port_) : 0;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "orconfig.h"
|
#include "orconfig.h"
|
||||||
#include "lib/cc/torint.h"
|
#include "lib/cc/torint.h"
|
||||||
#include "lib/log/util_bug.h"
|
#include "lib/log/util_bug.h"
|
||||||
#include "lib/net/ipv6.h"
|
#include "lib/net/inaddr_st.h"
|
||||||
#include "lib/net/nettypes.h"
|
#include "lib/net/nettypes.h"
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
@ -204,8 +204,6 @@ tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u)
|
|||||||
*/
|
*/
|
||||||
#define TOR_ADDR_BUF_LEN 48
|
#define TOR_ADDR_BUF_LEN 48
|
||||||
|
|
||||||
MOCK_DECL(int, tor_addr_lookup,(const char *name, uint16_t family,
|
|
||||||
tor_addr_t *addr_out));
|
|
||||||
char *tor_addr_to_str_dup(const tor_addr_t *addr) ATTR_MALLOC;
|
char *tor_addr_to_str_dup(const tor_addr_t *addr) ATTR_MALLOC;
|
||||||
|
|
||||||
/** Wrapper function of fmt_addr_impl(). It does not decorate IPv6
|
/** Wrapper function of fmt_addr_impl(). It does not decorate IPv6
|
||||||
@ -263,9 +261,6 @@ int tor_addr_to_PTR_name(char *out, size_t outlen,
|
|||||||
int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
|
int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
|
||||||
int family, int accept_regular);
|
int family, int accept_regular);
|
||||||
|
|
||||||
int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out,
|
|
||||||
uint16_t *port_out);
|
|
||||||
|
|
||||||
/* Does the address * yield an AF_UNSPEC wildcard address (1),
|
/* Does the address * yield an AF_UNSPEC wildcard address (1),
|
||||||
* which expands to corresponding wildcard IPv4 and IPv6 rules, and do we
|
* which expands to corresponding wildcard IPv4 and IPv6 rules, and do we
|
||||||
* allow *4 and *6 for IPv4 and IPv6 wildcards, respectively;
|
* allow *4 and *6 for IPv4 and IPv6 wildcards, respectively;
|
||||||
@ -330,8 +325,6 @@ int tor_addr_port_parse(int severity, const char *addrport,
|
|||||||
int tor_addr_hostname_is_local(const char *name);
|
int tor_addr_hostname_is_local(const char *name);
|
||||||
|
|
||||||
/* IPv4 helpers */
|
/* 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,
|
int parse_port_range(const char *port, uint16_t *port_min_out,
|
||||||
uint16_t *port_max_out);
|
uint16_t *port_max_out);
|
||||||
int addr_mask_get_bits(uint32_t mask);
|
int addr_mask_get_bits(uint32_t mask);
|
||||||
|
@ -4,20 +4,20 @@
|
|||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file ipv6.c
|
* \file inaddr.c
|
||||||
* \brief Functions for encoding and decoding IPv6 addresses
|
* \brief Convert in_addr and in6_addr to and from strings.
|
||||||
*
|
|
||||||
* (Because these functions are generic, they can also handle IPv4 addresses).
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include "lib/net/ipv6.h"
|
#include "lib/net/inaddr.h"
|
||||||
#include "lib/net/ipv4.h"
|
|
||||||
#include "lib/string/util_string.h"
|
#include "lib/cc/torint.h"
|
||||||
#include "lib/string/compat_string.h"
|
#include "lib/log/util_bug.h"
|
||||||
|
#include "lib/net/inaddr_st.h"
|
||||||
#include "lib/string/compat_ctype.h"
|
#include "lib/string/compat_ctype.h"
|
||||||
|
#include "lib/string/compat_string.h"
|
||||||
#include "lib/string/printf.h"
|
#include "lib/string/printf.h"
|
||||||
#include "lib/string/scanf.h"
|
#include "lib/string/scanf.h"
|
||||||
#include "lib/log/util_bug.h"
|
#include "lib/string/util_string.h"
|
||||||
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
#ifdef HAVE_ARPA_INET_H
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -26,6 +26,45 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set *addr to the IP address (in dotted-quad notation) stored in *str.
|
||||||
|
* Return 1 on success, 0 if *str is badly formatted.
|
||||||
|
* (Like inet_aton(str,addr), but works on Windows and Solaris.)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
tor_inet_aton(const char *str, struct in_addr* addr)
|
||||||
|
{
|
||||||
|
unsigned a,b,c,d;
|
||||||
|
char more;
|
||||||
|
if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a,&b,&c,&d,&more) != 4)
|
||||||
|
return 0;
|
||||||
|
if (a > 255) return 0;
|
||||||
|
if (b > 255) return 0;
|
||||||
|
if (c > 255) return 0;
|
||||||
|
if (d > 255) return 0;
|
||||||
|
addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
|
||||||
|
* write it as a string into the <b>buf_len</b>-byte buffer in
|
||||||
|
* <b>buf</b>. Returns a non-negative integer on success.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
|
||||||
|
{
|
||||||
|
uint32_t a = ntohl(in->s_addr);
|
||||||
|
return tor_snprintf(buf, buf_len, "%d.%d.%d.%d",
|
||||||
|
(int)(uint8_t)((a>>24)&0xff),
|
||||||
|
(int)(uint8_t)((a>>16)&0xff),
|
||||||
|
(int)(uint8_t)((a>>8 )&0xff),
|
||||||
|
(int)(uint8_t)((a )&0xff));
|
||||||
|
}
|
||||||
|
|
||||||
/** Given <b>af</b>==AF_INET and <b>src</b> a struct in_addr, or
|
/** Given <b>af</b>==AF_INET and <b>src</b> a struct in_addr, or
|
||||||
* <b>af</b>==AF_INET6 and <b>src</b> a struct in6_addr, try to format the
|
* <b>af</b>==AF_INET6 and <b>src</b> a struct in6_addr, try to format the
|
||||||
* address and store it in the <b>len</b>-byte buffer <b>dst</b>. Returns
|
* address and store it in the <b>len</b>-byte buffer <b>dst</b>. Returns
|
@ -4,18 +4,24 @@
|
|||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file ipv4.h
|
* \file inaddr.h
|
||||||
* \brief Header for ipv4.c
|
* \brief Header for inaddr.c.
|
||||||
**/
|
**/
|
||||||
#ifndef TOR_IPV4_H
|
|
||||||
#define TOR_IPV4_H
|
|
||||||
|
|
||||||
|
#ifndef TOR_INADDR_H
|
||||||
|
#define TOR_INADDR_H
|
||||||
|
|
||||||
|
#include "orconfig.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct in_addr;
|
struct in_addr;
|
||||||
|
|
||||||
int tor_inet_aton(const char *str, struct in_addr *addr);
|
int tor_inet_aton(const char *str, struct in_addr *addr);
|
||||||
/** Length of a buffer to allocate to hold the results of tor_inet_ntoa.*/
|
/** Length of a buffer to allocate to hold the results of tor_inet_ntoa.*/
|
||||||
#define INET_NTOA_BUF_LEN 16
|
#define INET_NTOA_BUF_LEN 16
|
||||||
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
|
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
|
||||||
|
|
||||||
|
const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
|
||||||
|
int tor_inet_pton(int af, const char *src, void *dst);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -4,25 +4,29 @@
|
|||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file ipv6.h
|
* \file inaddr_st.h
|
||||||
* \brief Header for ipv6.c
|
*
|
||||||
|
* \brief Define in6_addr, its members, and related types on platforms that
|
||||||
|
* lack it.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef TOR_IPV6_H
|
#ifndef TOR_INADDR_ST_H
|
||||||
#define TOR_IPV6_H
|
#define TOR_INADDR_ST_H
|
||||||
|
|
||||||
#include "orconfig.h"
|
|
||||||
#include <stddef.h>
|
|
||||||
#ifdef HAVE_NETINET_IN6_H
|
#ifdef HAVE_NETINET_IN6_H
|
||||||
#include <netinet/in6.h>
|
#include <netinet/in6.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "lib/cc/torint.h"
|
#include "lib/cc/torint.h"
|
||||||
|
|
||||||
|
struct in_addr;
|
||||||
|
|
||||||
/** Implementation of struct in6_addr for platforms that do not have it.
|
/** Implementation of struct in6_addr for platforms that do not have it.
|
||||||
* Generally, these platforms are ones without IPv6 support, but we want to
|
* Generally, these platforms are ones without IPv6 support, but we want to
|
||||||
* have a working in6_addr there anyway, so we can use it to parse IPv6
|
* have a working in6_addr there anyway, so we can use it to parse IPv6
|
||||||
@ -85,7 +89,4 @@ struct sockaddr_in6 {
|
|||||||
};
|
};
|
||||||
#endif /* !defined(HAVE_STRUCT_SOCKADDR_IN6) */
|
#endif /* !defined(HAVE_STRUCT_SOCKADDR_IN6) */
|
||||||
|
|
||||||
const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
|
#endif /* TOR_INADDR_ST_H */
|
||||||
int tor_inet_pton(int af, const char *src, void *dst);
|
|
||||||
|
|
||||||
#endif
|
|
@ -10,8 +10,7 @@ src_lib_libtor_net_a_SOURCES = \
|
|||||||
src/lib/net/alertsock.c \
|
src/lib/net/alertsock.c \
|
||||||
src/lib/net/buffers_net.c \
|
src/lib/net/buffers_net.c \
|
||||||
src/lib/net/gethostname.c \
|
src/lib/net/gethostname.c \
|
||||||
src/lib/net/ipv4.c \
|
src/lib/net/inaddr.c \
|
||||||
src/lib/net/ipv6.c \
|
|
||||||
src/lib/net/resolve.c \
|
src/lib/net/resolve.c \
|
||||||
src/lib/net/socket.c
|
src/lib/net/socket.c
|
||||||
|
|
||||||
@ -25,8 +24,8 @@ noinst_HEADERS += \
|
|||||||
src/lib/net/alertsock.h \
|
src/lib/net/alertsock.h \
|
||||||
src/lib/net/buffers_net.h \
|
src/lib/net/buffers_net.h \
|
||||||
src/lib/net/gethostname.h \
|
src/lib/net/gethostname.h \
|
||||||
src/lib/net/ipv4.h \
|
src/lib/net/inaddr.h \
|
||||||
src/lib/net/ipv6.h \
|
src/lib/net/inaddr_st.h \
|
||||||
src/lib/net/nettypes.h \
|
src/lib/net/nettypes.h \
|
||||||
src/lib/net/resolve.h \
|
src/lib/net/resolve.h \
|
||||||
src/lib/net/socket.h \
|
src/lib/net/socket.h \
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
/* Copyright (c) 2003-2004, Roger Dingledine
|
|
||||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
|
||||||
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
|
||||||
/* See LICENSE for licensing information */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file ipv4.c
|
|
||||||
* \brief Functions for encoding and decoding IPv4 addresses into strings
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "orconfig.h"
|
|
||||||
#include "lib/cc/torint.h"
|
|
||||||
#include "lib/net/ipv4.h"
|
|
||||||
#include "lib/string/printf.h"
|
|
||||||
#include "lib/string/scanf.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Set *addr to the IP address (in dotted-quad notation) stored in *str.
|
|
||||||
* Return 1 on success, 0 if *str is badly formatted.
|
|
||||||
* (Like inet_aton(str,addr), but works on Windows and Solaris.)
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tor_inet_aton(const char *str, struct in_addr* addr)
|
|
||||||
{
|
|
||||||
unsigned a,b,c,d;
|
|
||||||
char more;
|
|
||||||
if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a,&b,&c,&d,&more) != 4)
|
|
||||||
return 0;
|
|
||||||
if (a > 255) return 0;
|
|
||||||
if (b > 255) return 0;
|
|
||||||
if (c > 255) return 0;
|
|
||||||
if (d > 255) return 0;
|
|
||||||
addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
|
|
||||||
* write it as a string into the <b>buf_len</b>-byte buffer in
|
|
||||||
* <b>buf</b>. Returns a non-negative integer on success.
|
|
||||||
* Returns -1 on failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
|
|
||||||
{
|
|
||||||
uint32_t a = ntohl(in->s_addr);
|
|
||||||
return tor_snprintf(buf, buf_len, "%d.%d.%d.%d",
|
|
||||||
(int)(uint8_t)((a>>24)&0xff),
|
|
||||||
(int)(uint8_t)((a>>16)&0xff),
|
|
||||||
(int)(uint8_t)((a>>8 )&0xff),
|
|
||||||
(int)(uint8_t)((a )&0xff));
|
|
||||||
}
|
|
@ -9,8 +9,12 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include "lib/net/resolve.h"
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#include "lib/net/address.h"
|
#include "lib/net/address.h"
|
||||||
|
#include "lib/net/inaddr.h"
|
||||||
#include "lib/malloc/util_malloc.h"
|
#include "lib/malloc/util_malloc.h"
|
||||||
|
#include "lib/string/parse_int.h"
|
||||||
|
#include "lib/string/util_string.h"
|
||||||
|
|
||||||
#include "siphash.h"
|
#include "siphash.h"
|
||||||
#include "ht.h"
|
#include "ht.h"
|
||||||
@ -52,6 +56,185 @@ tor_lookup_hostname,(const char *name, uint32_t *addr))
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
|
||||||
|
* *<b>addr</b> to the proper IP address and family. The <b>family</b>
|
||||||
|
* argument (which must be AF_INET, AF_INET6, or AF_UNSPEC) declares a
|
||||||
|
* <i>preferred</i> family, though another one may be returned if only one
|
||||||
|
* family is implemented for this address.
|
||||||
|
*
|
||||||
|
* Return 0 on success, -1 on failure; 1 on transient failure.
|
||||||
|
*/
|
||||||
|
MOCK_IMPL(int,
|
||||||
|
tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
|
||||||
|
{
|
||||||
|
/* Perhaps eventually this should be replaced by a tor_getaddrinfo or
|
||||||
|
* something.
|
||||||
|
*/
|
||||||
|
struct in_addr iaddr;
|
||||||
|
struct in6_addr iaddr6;
|
||||||
|
tor_assert(name);
|
||||||
|
tor_assert(addr);
|
||||||
|
tor_assert(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC);
|
||||||
|
if (!*name) {
|
||||||
|
/* Empty address is an error. */
|
||||||
|
return -1;
|
||||||
|
} else if (tor_inet_pton(AF_INET, name, &iaddr)) {
|
||||||
|
/* It's an IPv4 IP. */
|
||||||
|
if (family == AF_INET6)
|
||||||
|
return -1;
|
||||||
|
tor_addr_from_in(addr, &iaddr);
|
||||||
|
return 0;
|
||||||
|
} else if (tor_inet_pton(AF_INET6, name, &iaddr6)) {
|
||||||
|
if (family == AF_INET)
|
||||||
|
return -1;
|
||||||
|
tor_addr_from_in6(addr, &iaddr6);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
#ifdef HAVE_GETADDRINFO
|
||||||
|
int err;
|
||||||
|
struct addrinfo *res=NULL, *res_p;
|
||||||
|
struct addrinfo *best=NULL;
|
||||||
|
struct addrinfo hints;
|
||||||
|
int result = -1;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = family;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
err = tor_getaddrinfo(name, NULL, &hints, &res);
|
||||||
|
/* The check for 'res' here shouldn't be necessary, but it makes static
|
||||||
|
* analysis tools happy. */
|
||||||
|
if (!err && res) {
|
||||||
|
best = NULL;
|
||||||
|
for (res_p = res; res_p; res_p = res_p->ai_next) {
|
||||||
|
if (family == AF_UNSPEC) {
|
||||||
|
if (res_p->ai_family == AF_INET) {
|
||||||
|
best = res_p;
|
||||||
|
break;
|
||||||
|
} else if (res_p->ai_family == AF_INET6 && !best) {
|
||||||
|
best = res_p;
|
||||||
|
}
|
||||||
|
} else if (family == res_p->ai_family) {
|
||||||
|
best = res_p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!best)
|
||||||
|
best = res;
|
||||||
|
if (best->ai_family == AF_INET) {
|
||||||
|
tor_addr_from_in(addr,
|
||||||
|
&((struct sockaddr_in*)best->ai_addr)->sin_addr);
|
||||||
|
result = 0;
|
||||||
|
} else if (best->ai_family == AF_INET6) {
|
||||||
|
tor_addr_from_in6(addr,
|
||||||
|
&((struct sockaddr_in6*)best->ai_addr)->sin6_addr);
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
tor_freeaddrinfo(res);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return (err == EAI_AGAIN) ? 1 : -1;
|
||||||
|
#else /* !(defined(HAVE_GETADDRINFO)) */
|
||||||
|
struct hostent *ent;
|
||||||
|
int err;
|
||||||
|
#ifdef HAVE_GETHOSTBYNAME_R_6_ARG
|
||||||
|
char buf[2048];
|
||||||
|
struct hostent hostent;
|
||||||
|
int r;
|
||||||
|
r = gethostbyname_r(name, &hostent, buf, sizeof(buf), &ent, &err);
|
||||||
|
#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
|
||||||
|
char buf[2048];
|
||||||
|
struct hostent hostent;
|
||||||
|
ent = gethostbyname_r(name, &hostent, buf, sizeof(buf), &err);
|
||||||
|
#elif defined(HAVE_GETHOSTBYNAME_R_3_ARG)
|
||||||
|
struct hostent_data data;
|
||||||
|
struct hostent hent;
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
err = gethostbyname_r(name, &hent, &data);
|
||||||
|
ent = err ? NULL : &hent;
|
||||||
|
#else
|
||||||
|
ent = gethostbyname(name);
|
||||||
|
#ifdef _WIN32
|
||||||
|
err = WSAGetLastError();
|
||||||
|
#else
|
||||||
|
err = h_errno;
|
||||||
|
#endif
|
||||||
|
#endif /* defined(HAVE_GETHOSTBYNAME_R_6_ARG) || ... */
|
||||||
|
if (ent) {
|
||||||
|
if (ent->h_addrtype == AF_INET) {
|
||||||
|
tor_addr_from_in(addr, (struct in_addr*) ent->h_addr);
|
||||||
|
} else if (ent->h_addrtype == AF_INET6) {
|
||||||
|
tor_addr_from_in6(addr, (struct in6_addr*) ent->h_addr);
|
||||||
|
} else {
|
||||||
|
tor_assert(0); // LCOV_EXCL_LINE: gethostbyname() returned bizarre type
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
return (err == WSATRY_AGAIN) ? 1 : -1;
|
||||||
|
#else
|
||||||
|
return (err == TRY_AGAIN) ? 1 : -1;
|
||||||
|
#endif
|
||||||
|
#endif /* defined(HAVE_GETADDRINFO) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Parse an address or address-port combination from <b>s</b>, resolve the
|
||||||
|
* address as needed, and put the result in <b>addr_out</b> and (optionally)
|
||||||
|
* <b>port_out</b>. Return 0 on success, negative on failure. */
|
||||||
|
int
|
||||||
|
tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
|
||||||
|
{
|
||||||
|
const char *port;
|
||||||
|
tor_addr_t addr;
|
||||||
|
uint16_t portval;
|
||||||
|
char *tmp = NULL;
|
||||||
|
|
||||||
|
tor_assert(s);
|
||||||
|
tor_assert(addr_out);
|
||||||
|
|
||||||
|
s = eat_whitespace(s);
|
||||||
|
|
||||||
|
if (*s == '[') {
|
||||||
|
port = strstr(s, "]");
|
||||||
|
if (!port)
|
||||||
|
goto err;
|
||||||
|
tmp = tor_strndup(s+1, port-(s+1));
|
||||||
|
port = port+1;
|
||||||
|
if (*port == ':')
|
||||||
|
port++;
|
||||||
|
else
|
||||||
|
port = NULL;
|
||||||
|
} else {
|
||||||
|
port = strchr(s, ':');
|
||||||
|
if (port)
|
||||||
|
tmp = tor_strndup(s, port-s);
|
||||||
|
else
|
||||||
|
tmp = tor_strdup(s);
|
||||||
|
if (port)
|
||||||
|
++port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tor_addr_lookup(tmp, AF_UNSPEC, &addr) != 0)
|
||||||
|
goto err;
|
||||||
|
tor_free(tmp);
|
||||||
|
|
||||||
|
if (port) {
|
||||||
|
portval = (int) tor_parse_long(port, 10, 1, 65535, NULL, NULL);
|
||||||
|
if (!portval)
|
||||||
|
goto err;
|
||||||
|
} else {
|
||||||
|
portval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port_out)
|
||||||
|
*port_out = portval;
|
||||||
|
tor_addr_copy(addr_out, &addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
tor_free(tmp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_SANDBOX_GETADDRINFO
|
#ifdef USE_SANDBOX_GETADDRINFO
|
||||||
/** True if we should only return cached values */
|
/** True if we should only return cached values */
|
||||||
static int sandbox_getaddrinfo_is_active = 0;
|
static int sandbox_getaddrinfo_is_active = 0;
|
||||||
|
@ -22,7 +22,13 @@
|
|||||||
#define USE_SANDBOX_GETADDRINFO
|
#define USE_SANDBOX_GETADDRINFO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MOCK_DECL(int,tor_lookup_hostname,(const char *name, uint32_t *addr));
|
struct tor_addr_t;
|
||||||
|
|
||||||
|
MOCK_DECL(int, tor_lookup_hostname,(const char *name, uint32_t *addr));
|
||||||
|
MOCK_DECL(int, tor_addr_lookup,(const char *name, uint16_t family,
|
||||||
|
struct tor_addr_t *addr_out));
|
||||||
|
int tor_addr_port_lookup(const char *s, struct tor_addr_t *addr_out,
|
||||||
|
uint16_t *port_out);
|
||||||
|
|
||||||
struct addrinfo;
|
struct addrinfo;
|
||||||
#ifdef USE_SANDBOX_GETADDRINFO
|
#ifdef USE_SANDBOX_GETADDRINFO
|
||||||
|
@ -10,71 +10,16 @@
|
|||||||
#include "test/test.h"
|
#include "test/test.h"
|
||||||
#include "feature/client/addressmap.h"
|
#include "feature/client/addressmap.h"
|
||||||
#include "test/log_test_helpers.h"
|
#include "test/log_test_helpers.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_UN_H
|
#ifdef HAVE_SYS_UN_H
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#endif
|
#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
|
static void
|
||||||
test_addr_basic(void *arg)
|
test_addr_basic(void *arg)
|
||||||
{
|
{
|
||||||
uint32_t u32;
|
(void) arg;
|
||||||
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);
|
|
||||||
|
|
||||||
tt_int_op(0,OP_EQ, addr_mask_get_bits(0x0u));
|
tt_int_op(0,OP_EQ, addr_mask_get_bits(0x0u));
|
||||||
tt_int_op(32,OP_EQ, addr_mask_get_bits(0xFFFFFFFFu));
|
tt_int_op(32,OP_EQ, addr_mask_get_bits(0xFFFFFFFFu));
|
||||||
@ -102,8 +47,7 @@ test_addr_basic(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
UNMOCK(tor_addr_lookup);
|
;
|
||||||
tor_free(cp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define test_op_ip6_(a,op,b,e1,e2) \
|
#define test_op_ip6_(a,op,b,e1,e2) \
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#define ROUTERSET_PRIVATE
|
#define ROUTERSET_PRIVATE
|
||||||
#include "core/or/or.h"
|
#include "core/or/or.h"
|
||||||
#include "lib/net/address.h"
|
#include "lib/net/address.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
#include "feature/client/addressmap.h"
|
#include "feature/client/addressmap.h"
|
||||||
#include "feature/client/bridges.h"
|
#include "feature/client/bridges.h"
|
||||||
#include "core/or/circuitmux_ewma.h"
|
#include "core/or/circuitmux_ewma.h"
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "feature/rend/rendcache.h"
|
#include "feature/rend/rendcache.h"
|
||||||
#include "feature/dircache/directory.h"
|
#include "feature/dircache/directory.h"
|
||||||
#include "core/or/connection_or.h"
|
#include "core/or/connection_or.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#include "test/test_connection.h"
|
#include "test/test_connection.h"
|
||||||
#include "test/test_helpers.h"
|
#include "test/test_helpers.h"
|
||||||
@ -899,4 +900,3 @@ struct testcase_t connection_tests[] = {
|
|||||||
{ "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL },
|
{ "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL },
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "feature/nodelist/nodelist.h"
|
#include "feature/nodelist/nodelist.h"
|
||||||
#include "test/test.h"
|
#include "test/test.h"
|
||||||
#include "test/test_helpers.h"
|
#include "test/test_helpers.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#include "feature/control/control_connection_st.h"
|
#include "feature/control/control_connection_st.h"
|
||||||
#include "feature/dirclient/download_status_st.h"
|
#include "feature/dirclient/download_status_st.h"
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "core/or/relay.h"
|
#include "core/or/relay.h"
|
||||||
#include "feature/nodelist/routerlist.h"
|
#include "feature/nodelist/routerlist.h"
|
||||||
#include "lib/encoding/confline.h"
|
#include "lib/encoding/confline.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#include "core/or/cell_st.h"
|
#include "core/or/cell_st.h"
|
||||||
#include "core/or/connection_st.h"
|
#include "core/or/connection_st.h"
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "lib/encoding/confline.h"
|
#include "lib/encoding/confline.h"
|
||||||
#include "core/or/policies.h"
|
#include "core/or/policies.h"
|
||||||
#include "test/test_helpers.h"
|
#include "test/test_helpers.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#define NS_MODULE test_options
|
#define NS_MODULE test_options
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "test/test.h"
|
#include "test/test.h"
|
||||||
#include "lib/process/subprocess.h"
|
#include "lib/process/subprocess.h"
|
||||||
#include "lib/encoding/confline.h"
|
#include "lib/encoding/confline.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
|
|
||||||
#include "app/config/or_state_st.h"
|
#include "app/config/or_state_st.h"
|
||||||
|
|
||||||
|
@ -41,7 +41,8 @@ ENABLE_GCC_WARNING(redundant-decls)
|
|||||||
#include "lib/log/torlog.h"
|
#include "lib/log/torlog.h"
|
||||||
#include "lib/malloc/util_malloc.h"
|
#include "lib/malloc/util_malloc.h"
|
||||||
#include "lib/net/address.h"
|
#include "lib/net/address.h"
|
||||||
#include "lib/net/ipv4.h"
|
#include "lib/net/inaddr.h"
|
||||||
|
#include "lib/net/resolve.h"
|
||||||
#include "lib/string/compat_string.h"
|
#include "lib/string/compat_string.h"
|
||||||
#include "lib/string/printf.h"
|
#include "lib/string/printf.h"
|
||||||
|
|
||||||
@ -170,19 +171,22 @@ parse_commandline(int argc, char **argv)
|
|||||||
} else if (!strcmp(argv[i], "-v")) {
|
} else if (!strcmp(argv[i], "-v")) {
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
} else if (!strcmp(argv[i], "-a")) {
|
} else if (!strcmp(argv[i], "-a")) {
|
||||||
uint32_t addr;
|
tor_addr_t addr;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
char b[INET_NTOA_BUF_LEN];
|
|
||||||
struct in_addr in;
|
|
||||||
if (i+1>=argc) {
|
if (i+1>=argc) {
|
||||||
fprintf(stderr, "No argument to -a\n");
|
fprintf(stderr, "No argument to -a\n");
|
||||||
return 1;
|
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;
|
return 1;
|
||||||
in.s_addr = htonl(addr);
|
}
|
||||||
tor_inet_ntoa(&in, b, sizeof(b));
|
if (tor_addr_family(&addr) != AF_INET) {
|
||||||
tor_asprintf(&address, "%s:%d", b, (int)port);
|
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")) {
|
} else if (!strcmp(argv[i], "--create-identity-key")) {
|
||||||
make_new_id = 1;
|
make_new_id = 1;
|
||||||
} else if (!strcmp(argv[i], "--passphrase-fd")) {
|
} else if (!strcmp(argv[i], "--passphrase-fd")) {
|
||||||
|
@ -197,12 +197,14 @@ socks5_reason_to_string(char reason)
|
|||||||
* address (in host order) into *<b>result_addr</b>.
|
* address (in host order) into *<b>result_addr</b>.
|
||||||
*/
|
*/
|
||||||
static int
|
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,
|
int reverse, int version,
|
||||||
tor_addr_t *result_addr, char **result_hostname)
|
tor_addr_t *result_addr, char **result_hostname)
|
||||||
{
|
{
|
||||||
int s = -1;
|
int s = -1;
|
||||||
struct sockaddr_in socksaddr;
|
struct sockaddr_storage ss;
|
||||||
|
socklen_t socklen;
|
||||||
char *req = NULL;
|
char *req = NULL;
|
||||||
ssize_t len = 0;
|
ssize_t len = 0;
|
||||||
|
|
||||||
@ -219,11 +221,10 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&socksaddr, 0, sizeof(socksaddr));
|
socklen = tor_addr_to_sockaddr(sockshost, socksport,
|
||||||
socksaddr.sin_family = AF_INET;
|
(struct sockaddr *)&ss, sizeof(ss));
|
||||||
socksaddr.sin_port = htons(socksport);
|
|
||||||
socksaddr.sin_addr.s_addr = htonl(sockshost);
|
if (connect(s, (struct sockaddr*)&ss, sizeof(socklen))) {
|
||||||
if (connect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) {
|
|
||||||
log_sock_error("connecting to SOCKS host", s);
|
log_sock_error("connecting to SOCKS host", s);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -346,7 +347,7 @@ usage(void)
|
|||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
uint32_t sockshost;
|
tor_addr_t sockshost;
|
||||||
uint16_t socksport = 0, port_option = 0;
|
uint16_t socksport = 0, port_option = 0;
|
||||||
int isSocks4 = 0, isVerbose = 0, isReverse = 0;
|
int isSocks4 = 0, isVerbose = 0, isReverse = 0;
|
||||||
char **arg;
|
char **arg;
|
||||||
@ -414,7 +415,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
log_debug(LD_CONFIG, "defaulting to localhost");
|
log_debug(LD_CONFIG, "defaulting to localhost");
|
||||||
sockshost = 0x7f000001u; /* localhost */
|
tor_addr_from_ipv4h(&sockshost, 0x7f000001u); /* localhost */
|
||||||
if (port_option) {
|
if (port_option) {
|
||||||
log_debug(LD_CONFIG, "Using port %d", (int)port_option);
|
log_debug(LD_CONFIG, "Using port %d", (int)port_option);
|
||||||
socksport = port_option;
|
socksport = port_option;
|
||||||
@ -423,7 +424,7 @@ main(int argc, char **argv)
|
|||||||
socksport = 9050; /* 9050 */
|
socksport = 9050; /* 9050 */
|
||||||
}
|
}
|
||||||
} else if (n_args == 2) {
|
} 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]);
|
fprintf(stderr, "Couldn't parse/resolve address %s", arg[1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -445,7 +446,7 @@ main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_resolve(arg[0], sockshost, socksport, isReverse,
|
if (do_resolve(arg[0], &sockshost, socksport, isReverse,
|
||||||
isSocks4 ? 4 : 5, &result,
|
isSocks4 ? 4 : 5, &result,
|
||||||
&result_hostname))
|
&result_hostname))
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user