|
|
c88997 |
From a58f31659a924c59f6342d79d2c19ee956453d82 Mon Sep 17 00:00:00 2001
|
|
|
c88997 |
From: Mark Andrews <marka@isc.org>
|
|
|
c88997 |
Date: Sat, 18 Oct 2014 12:40:13 +1100
|
|
|
c88997 |
Subject: [PATCH 2/2] 3980. [bug] Improve --with-tuning=large by
|
|
|
c88997 |
self tuning of SO_RCVBUF size. [RT #37187]
|
|
|
c88997 |
|
|
|
c88997 |
(cherry picked from commit 871f3c8beeb2134b17414ec167b90a57adb8e122)
|
|
|
c88997 |
---
|
|
|
c88997 |
lib/isc/unix/socket.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++----
|
|
|
c88997 |
1 file changed, 61 insertions(+), 5 deletions(-)
|
|
|
c88997 |
|
|
|
c88997 |
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
|
|
|
c88997 |
index af0c3bc..90953ff 100644
|
|
|
c88997 |
--- a/lib/isc/unix/socket.c
|
|
|
c88997 |
+++ b/lib/isc/unix/socket.c
|
|
|
c88997 |
@@ -2245,6 +2245,62 @@ free_socket(isc__socket_t **socketp) {
|
|
|
c88997 |
*socketp = NULL;
|
|
|
c88997 |
}
|
|
|
c88997 |
|
|
|
c88997 |
+#ifdef SO_RCVBUF
|
|
|
c88997 |
+static isc_once_t rcvbuf_once = ISC_ONCE_INIT;
|
|
|
c88997 |
+static int rcvbuf = RCVBUFSIZE;
|
|
|
c88997 |
+
|
|
|
c88997 |
+static void
|
|
|
c88997 |
+set_rcvbuf(void) {
|
|
|
c88997 |
+ int fd;
|
|
|
c88997 |
+ int max = rcvbuf, min;
|
|
|
c88997 |
+ ISC_SOCKADDR_LEN_T len;
|
|
|
c88997 |
+
|
|
|
c88997 |
+ fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
c88997 |
+#if defined(ISC_PLATFORM_HAVEIPV6)
|
|
|
c88997 |
+ if (fd == -1) {
|
|
|
c88997 |
+ switch (errno) {
|
|
|
c88997 |
+ case EPROTONOSUPPORT:
|
|
|
c88997 |
+ case EPFNOSUPPORT:
|
|
|
c88997 |
+ case EAFNOSUPPORT:
|
|
|
c88997 |
+ /*
|
|
|
c88997 |
+ * Linux 2.2 (and maybe others) return EINVAL instead of
|
|
|
c88997 |
+ * EAFNOSUPPORT.
|
|
|
c88997 |
+ */
|
|
|
c88997 |
+ case EINVAL:
|
|
|
c88997 |
+ fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
c88997 |
+ break;
|
|
|
c88997 |
+ }
|
|
|
c88997 |
+ }
|
|
|
c88997 |
+#endif
|
|
|
c88997 |
+ if (fd == -1)
|
|
|
c88997 |
+ return;
|
|
|
c88997 |
+
|
|
|
c88997 |
+ len = sizeof(min);
|
|
|
c88997 |
+ if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&min, &len) >= 0 &&
|
|
|
c88997 |
+ min < rcvbuf) {
|
|
|
c88997 |
+ again:
|
|
|
c88997 |
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf,
|
|
|
c88997 |
+ sizeof(rcvbuf)) == -1) {
|
|
|
c88997 |
+ if (errno == ENOBUFS && rcvbuf > min) {
|
|
|
c88997 |
+ max = rcvbuf - 1;
|
|
|
c88997 |
+ rcvbuf = (rcvbuf + min) / 2;
|
|
|
c88997 |
+ goto again;
|
|
|
c88997 |
+ } else {
|
|
|
c88997 |
+ rcvbuf = min;
|
|
|
c88997 |
+ goto cleanup;
|
|
|
c88997 |
+ }
|
|
|
c88997 |
+ } else
|
|
|
c88997 |
+ min = rcvbuf;
|
|
|
c88997 |
+ if (min != max) {
|
|
|
c88997 |
+ rcvbuf = max;
|
|
|
c88997 |
+ goto again;
|
|
|
c88997 |
+ }
|
|
|
c88997 |
+ }
|
|
|
c88997 |
+ cleanup:
|
|
|
c88997 |
+ close (fd);
|
|
|
c88997 |
+}
|
|
|
c88997 |
+#endif
|
|
|
c88997 |
+
|
|
|
c88997 |
#ifdef SO_BSDCOMPAT
|
|
|
c88997 |
/*
|
|
|
c88997 |
* This really should not be necessary to do. Having to workout
|
|
|
c88997 |
@@ -2609,15 +2665,15 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
|
|
|
c88997 |
#if defined(SO_RCVBUF)
|
|
|
c88997 |
optlen = sizeof(size);
|
|
|
c88997 |
if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF,
|
|
|
c88997 |
- (void *)&size, &optlen) >= 0 &&
|
|
|
c88997 |
- size < RCVBUFSIZE) {
|
|
|
c88997 |
- size = RCVBUFSIZE;
|
|
|
c88997 |
+ (void *)&size, &optlen) >= 0 && size < rcvbuf) {
|
|
|
c88997 |
+ RUNTIME_CHECK(isc_once_do(&rcvbuf_once,
|
|
|
c88997 |
+ set_rcvbuf) == ISC_R_SUCCESS);
|
|
|
c88997 |
if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF,
|
|
|
c88997 |
- (void *)&size, sizeof(size)) == -1) {
|
|
|
c88997 |
+ (void *)&rcvbuf, sizeof(rcvbuf)) == -1) {
|
|
|
c88997 |
isc__strerror(errno, strbuf, sizeof(strbuf));
|
|
|
c88997 |
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
|
|
c88997 |
"setsockopt(%d, SO_RCVBUF, %d) %s: %s",
|
|
|
c88997 |
- sock->fd, size,
|
|
|
c88997 |
+ sock->fd, rcvbuf,
|
|
|
c88997 |
isc_msgcat_get(isc_msgcat,
|
|
|
c88997 |
ISC_MSGSET_GENERAL,
|
|
|
c88997 |
ISC_MSG_FAILED,
|
|
|
c88997 |
--
|
|
|
c88997 |
2.9.5
|
|
|
c88997 |
|