evdns: add new options -- so-rcvbuf/so-sndbuf

This will allow to customize SO_RCVBUF/SO_SNDBUF for nameservers in this
evdns_base, you may want to adjust them if the kernel starts dropping
udp packages.

(cherry picked from commit 538141eb7e590bc94c043b43b5e5483b13bc9c5e)
This commit is contained in:
Azat Khuzhin 2019-06-15 23:18:05 +03:00 committed by Azat Khuzhin
parent a09265aca0
commit 546a366ca3
No known key found for this signature in database
GPG Key ID: B86086848EF8686D
3 changed files with 55 additions and 1 deletions

30
evdns.c
View File

@ -346,6 +346,9 @@ struct evdns_base {
struct timeval global_getaddrinfo_allow_skew;
int so_rcvbuf;
int so_sndbuf;
int getaddrinfo_ipv4_timeouts;
int getaddrinfo_ipv6_timeouts;
int getaddrinfo_ipv4_answered;
@ -2538,6 +2541,23 @@ evdns_nameserver_add_impl_(struct evdns_base *base, const struct sockaddr *addre
}
}
if (base->so_rcvbuf) {
if (setsockopt(ns->socket, SOL_SOCKET, SO_RCVBUF,
(void *)&base->so_rcvbuf, sizeof(base->so_rcvbuf))) {
log(EVDNS_LOG_WARN, "Couldn't set SO_RCVBUF to %i", base->so_rcvbuf);
err = -SO_RCVBUF;
goto out2;
}
}
if (base->so_sndbuf) {
if (setsockopt(ns->socket, SOL_SOCKET, SO_SNDBUF,
(void *)&base->so_sndbuf, sizeof(base->so_sndbuf))) {
log(EVDNS_LOG_WARN, "Couldn't set SO_SNDBUF to %i", base->so_sndbuf);
err = -SO_SNDBUF;
goto out2;
}
}
memcpy(&ns->address, address, addrlen);
ns->addrlen = addrlen;
ns->state = 1;
@ -3531,6 +3551,16 @@ evdns_base_set_option_impl(struct evdns_base *base,
val);
memcpy(&base->global_nameserver_probe_initial_timeout, &tv,
sizeof(tv));
} else if (str_matches_option(option, "so-rcvbuf:")) {
int buf = strtoint(val);
if (!(flags & DNS_OPTION_MISC)) return 0;
log(EVDNS_LOG_DEBUG, "Setting SO_RCVBUF to %s", val);
base->so_rcvbuf = buf;
} else if (str_matches_option(option, "so-sndbuf:")) {
int buf = strtoint(val);
if (!(flags & DNS_OPTION_MISC)) return 0;
log(EVDNS_LOG_DEBUG, "Setting SO_SNDBUF to %s", val);
base->so_sndbuf = buf;
}
return 0;
}

View File

@ -455,7 +455,8 @@ void evdns_cancel_request(struct evdns_base *base, struct evdns_request *req);
The currently available configuration options are:
ndots, timeout, max-timeouts, max-inflight, attempts, randomize-case,
bind-to, initial-probe-timeout, getaddrinfo-allow-skew.
bind-to, initial-probe-timeout, getaddrinfo-allow-skew,
so-rcvbuf, so-sndbuf.
In versions before Libevent 2.0.3-alpha, the option name needed to end with
a colon.

View File

@ -2352,6 +2352,26 @@ end:
}
#endif
static void
test_set_so_rcvbuf_so_sndbuf(void *arg)
{
struct basic_test_data *data = arg;
struct evdns_base *dns_base;
dns_base = evdns_base_new(data->base, 0);
tt_assert(dns_base);
tt_assert(!evdns_base_set_option(dns_base, "so-rcvbuf", "10240"));
tt_assert(!evdns_base_set_option(dns_base, "so-sndbuf", "10240"));
/* actually check SO_RCVBUF/SO_SNDBUF not fails */
tt_assert(!evdns_base_nameserver_ip_add(dns_base, "127.0.0.1"));
end:
if (dns_base)
evdns_base_free(dns_base, 0);
}
#define DNS_LEGACY(name, flags) \
{ #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \
dns_##name }
@ -2421,6 +2441,9 @@ struct testcase_t dns_testcases[] = {
TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL },
#endif
{ "set_SO_RCVBUF_SO_SNDBUF", test_set_so_rcvbuf_so_sndbuf,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
END_OF_TESTCASES
};