mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-18 16:54:42 -04:00
Don't use a bind address for nameservers on loopback
If the user sets a bind address to use for nameservers, and a nameserver happens to be on 127.0.0.1, the nameserver will generally fail. This patch alters this behavior so that the bind address is only applied when the nameserver is on a non-loopback address.
This commit is contained in:
parent
0683950384
commit
8d4aaf9086
3
evdns.c
3
evdns.c
@ -2448,7 +2448,8 @@ _evdns_nameserver_add_impl(struct evdns_base *base, const struct sockaddr *addre
|
||||
if (ns->socket < 0) { err = 1; goto out1; }
|
||||
evutil_make_socket_nonblocking(ns->socket);
|
||||
|
||||
if (base->global_outgoing_addrlen) {
|
||||
if (base->global_outgoing_addrlen &&
|
||||
!evutil_sockaddr_is_loopback(address)) {
|
||||
if (bind(ns->socket,
|
||||
(struct sockaddr*)&base->global_outgoing_address,
|
||||
base->global_outgoing_addrlen) < 0) {
|
||||
|
22
evutil.c
22
evutil.c
@ -1849,3 +1849,25 @@ _evutil_weakrand(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
evutil_sockaddr_is_loopback(const struct sockaddr *addr)
|
||||
{
|
||||
static const char LOOPBACK_S6[16] =
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
|
||||
if (addr->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
|
||||
return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
|
||||
} else if (addr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
|
||||
/*
|
||||
int i;
|
||||
for (i=0;i<14;++i)
|
||||
if (sin6->sin6_addr.s6_addr[i] != 0)
|
||||
return 1;
|
||||
return sin6->sin6_addr.s6_addr[15] == 1;
|
||||
*/
|
||||
return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -275,6 +275,50 @@ regress_sockaddr_port_parse(void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
static struct sa_pred_ent {
|
||||
const char *parse;
|
||||
|
||||
int is_loopback;
|
||||
} sa_pred_entries[] = {
|
||||
{ "127.0.0.1", 1 },
|
||||
{ "127.0.3.2", 1 },
|
||||
{ "128.1.2.3", 0 },
|
||||
{ "18.0.0.1", 0 },
|
||||
{ "129.168.1.1", 0 },
|
||||
|
||||
{ "::1", 1 },
|
||||
{ "::0", 0 },
|
||||
{ "f::1", 0 },
|
||||
{ "::501", 0 },
|
||||
{ NULL, 0 },
|
||||
|
||||
};
|
||||
|
||||
static void
|
||||
test_evutil_sockaddr_predicates(void *ptr)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
int r, i;
|
||||
|
||||
for (i=0; sa_pred_entries[i].parse; ++i) {
|
||||
struct sa_pred_ent *ent = &sa_pred_entries[i];
|
||||
int len = sizeof(ss);
|
||||
|
||||
r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len);
|
||||
|
||||
if (r<0) {
|
||||
TT_FAIL(("Couldn't parse %s!", ent->parse));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sockaddr_is_loopback */
|
||||
if (ent->is_loopback != evutil_sockaddr_is_loopback((struct sockaddr*)&ss)) {
|
||||
TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected",
|
||||
ent->parse));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_evutil_strtoll(void *ptr)
|
||||
{
|
||||
@ -758,6 +802,7 @@ struct testcase_t util_testcases[] = {
|
||||
{ "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL },
|
||||
{ "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL },
|
||||
{ "sockaddr_port_parse", regress_sockaddr_port_parse, 0, NULL, NULL },
|
||||
{ "sockaddr_predicates", test_evutil_sockaddr_predicates, 0,NULL,NULL },
|
||||
{ "evutil_snprintf", test_evutil_snprintf, 0, NULL, NULL },
|
||||
{ "evutil_strtoll", test_evutil_strtoll, 0, NULL, NULL },
|
||||
{ "evutil_casecmp", test_evutil_casecmp, 0, NULL, NULL },
|
||||
|
@ -232,12 +232,15 @@ void evutil_adjust_hints_for_addrconfig(struct evutil_addrinfo *hints);
|
||||
int evutil_getaddrinfo_common(const char *nodename, const char *servname,
|
||||
struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum);
|
||||
|
||||
int
|
||||
evutil_getaddrinfo_async(struct evdns_base *dns_base,
|
||||
int evutil_getaddrinfo_async(struct evdns_base *dns_base,
|
||||
const char *nodename, const char *servname,
|
||||
const struct evutil_addrinfo *hints_in,
|
||||
void (*cb)(int, struct evutil_addrinfo *, void *), void *arg);
|
||||
|
||||
/** Return true iff sa is a looback address. (That is, it is 127.0.0.1/8, or
|
||||
* ::1). */
|
||||
int evutil_sockaddr_is_loopback(const struct sockaddr *sa);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user