]> granicus.if.org Git - libevent/commitdiff
evdns: add new options -- so-rcvbuf/so-sndbuf
authorAzat Khuzhin <azat@libevent.org>
Sat, 15 Jun 2019 20:18:05 +0000 (23:18 +0300)
committerAzat Khuzhin <a3at.mail@gmail.com>
Thu, 1 Aug 2019 21:05:49 +0000 (00:05 +0300)
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)

evdns.c
include/event2/dns.h
test/regress_dns.c

diff --git a/evdns.c b/evdns.c
index 1b8153662d8b2df5d95ad77acf6bfaca5df5553f..0a0e1ba6cbfc5e8bb1c8a9c59885ff6b13af8b47 100644 (file)
--- a/evdns.c
+++ b/evdns.c
@@ -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;
 }
index 3c548a1ec9fd5f75fb5d96441c0a2da254158a1e..13ce027e4a8c77081f0e90f621d3299041e1c911 100644 (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.
index 76b0b86ae8d8e662cef3a9d71ac8bfb8bda9e3a1..d2084b70e215a7527ed733709b622ffc238f1603 100644 (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
 };