Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
The Tor Project
Core
Tor
Commits
c2ddb7b2
Commit
c2ddb7b2
authored
Jul 10, 2018
by
Nick Mathewson
🎨
Browse files
Move tor_addr_{,port_}lookup to resolve.c
parent
5d8336c1
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/lib/net/address.c
View file @
c2ddb7b2
...
...
@@ -234,127 +234,6 @@ tor_addr_make_null(tor_addr_t *a, sa_family_t 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
* in RFC1918 or RFC4193 or RFC4291. (fec0::/10, deprecated by RFC3879, is
* also treated as internal for now.)
...
...
@@ -1324,64 +1203,6 @@ tor_addr_parse(tor_addr_t *addr, const char *src)
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
typedef
ULONG
(
WINAPI
*
GetAdaptersAddresses_fn_t
)(
ULONG
,
ULONG
,
PVOID
,
PIP_ADAPTER_ADDRESSES
,
PULONG
);
...
...
src/lib/net/address.h
View file @
c2ddb7b2
...
...
@@ -204,8 +204,6 @@ tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u)
*/
#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
;
/** 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
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),
* which expands to corresponding wildcard IPv4 and IPv6 rules, and do we
* allow *4 and *6 for IPv4 and IPv6 wildcards, respectively;
...
...
src/lib/net/resolve.c
View file @
c2ddb7b2
...
...
@@ -9,8 +9,12 @@
**/
#include
"lib/net/resolve.h"
#include
"lib/net/address.h"
#include
"lib/net/inaddr.h"
#include
"lib/malloc/util_malloc.h"
#include
"lib/string/parse_int.h"
#include
"lib/string/util_string.h"
#include
"siphash.h"
#include
"ht.h"
...
...
@@ -52,6 +56,185 @@ tor_lookup_hostname,(const char *name, uint32_t *addr))
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
/** True if we should only return cached values */
static
int
sandbox_getaddrinfo_is_active
=
0
;
...
...
src/lib/net/resolve.h
View file @
c2ddb7b2
...
...
@@ -22,7 +22,13 @@
#define USE_SANDBOX_GETADDRINFO
#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
;
#ifdef USE_SANDBOX_GETADDRINFO
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment