Merge branch 'set-sndbuf' into 'master'
Set sndbuf See merge request isc-projects/bind9!74
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,3 +1,5 @@
|
||||
5027. [func] Set SO_SNDBUF size on sockets. [GL #74]
|
||||
|
||||
5026. [bug] rndc reconfig should not touch already loaded zones.
|
||||
[GL #276]
|
||||
|
||||
|
||||
@@ -279,11 +279,14 @@ typedef isc_event_t intev_t;
|
||||
#ifdef TUNE_LARGE
|
||||
#ifdef sun
|
||||
#define RCVBUFSIZE (1*1024*1024)
|
||||
#define SNDBUFSIZE (1*1024*1024)
|
||||
#else
|
||||
#define RCVBUFSIZE (16*1024*1024)
|
||||
#define SNDBUFSIZE (16*1024*1024)
|
||||
#endif
|
||||
#else
|
||||
#define RCVBUFSIZE (32*1024)
|
||||
#define SNDBUFSIZE (32*1024)
|
||||
#endif /* TUNE_LARGE */
|
||||
|
||||
/*%
|
||||
@@ -2318,6 +2321,65 @@ set_rcvbuf(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SO_SNDBUF
|
||||
static isc_once_t sndbuf_once = ISC_ONCE_INIT;
|
||||
static int sndbuf = SNDBUFSIZE;
|
||||
|
||||
static void
|
||||
set_sndbuf(void) {
|
||||
int fd;
|
||||
int max = sndbuf, min;
|
||||
ISC_SOCKADDR_LEN_T len;
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
#if defined(ISC_PLATFORM_HAVEIPV6)
|
||||
if (fd == -1) {
|
||||
switch (errno) {
|
||||
case EPROTONOSUPPORT:
|
||||
case EPFNOSUPPORT:
|
||||
case EAFNOSUPPORT:
|
||||
/*
|
||||
* Linux 2.2 (and maybe others) return EINVAL instead of
|
||||
* EAFNOSUPPORT.
|
||||
*/
|
||||
case EINVAL:
|
||||
fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (fd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
len = sizeof(min);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&min, &len) == 0 &&
|
||||
min < sndbuf)
|
||||
{
|
||||
again:
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&sndbuf,
|
||||
sizeof(sndbuf)) == -1) {
|
||||
if (errno == ENOBUFS && sndbuf > min) {
|
||||
max = sndbuf - 1;
|
||||
sndbuf = (sndbuf + min) / 2;
|
||||
goto again;
|
||||
} else {
|
||||
sndbuf = min;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
min = sndbuf;
|
||||
}
|
||||
if (min != max) {
|
||||
sndbuf = max;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
close (fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SO_BSDCOMPAT
|
||||
/*
|
||||
* This really should not be necessary to do. Having to workout
|
||||
@@ -2401,7 +2463,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
|
||||
#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) || defined(SO_NOSIGPIPE)
|
||||
int on = 1;
|
||||
#endif
|
||||
#if defined(SO_RCVBUF)
|
||||
#if defined(SO_RCVBUF) || defined(SO_SNDBUF)
|
||||
ISC_SOCKADDR_LEN_T optlen;
|
||||
int size = 0;
|
||||
#endif
|
||||
@@ -2600,7 +2662,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
|
||||
set_tcp_maxseg(sock, 1280 - 20 - 40); /* 1280 - TCP - IPV6 */
|
||||
}
|
||||
|
||||
#if defined(USE_CMSG) || defined(SO_RCVBUF)
|
||||
#if defined(USE_CMSG) || defined(SO_RCVBUF) || defined(SO_SNDBUF)
|
||||
if (sock->type == isc_sockettype_udp) {
|
||||
|
||||
#if defined(USE_CMSG)
|
||||
@@ -2719,6 +2781,27 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SO_SNDBUF)
|
||||
optlen = sizeof(size);
|
||||
if (getsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF,
|
||||
(void *)&size, &optlen) == 0 && size < sndbuf) {
|
||||
RUNTIME_CHECK(isc_once_do(&sndbuf_once,
|
||||
set_sndbuf) == ISC_R_SUCCESS);
|
||||
if (setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF,
|
||||
(void *)&sndbuf, sizeof(sndbuf)) == -1) {
|
||||
strerror_r(errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"setsockopt(%d, SO_SNDBUF, %d) %s: %s",
|
||||
sock->fd, sndbuf,
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strbuf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef IPV6_RECVTCLASS
|
||||
if ((sock->pf == AF_INET6)
|
||||
@@ -2746,7 +2829,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
|
||||
strbuf);
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */
|
||||
#endif /* defined(USE_CMSG) || defined(SO_RCVBUF) || defined(SO_SNDBUF) */
|
||||
|
||||
setup_done:
|
||||
inc_stats(manager->stats, sock->statsindex[STATID_OPEN]);
|
||||
|
||||
Reference in New Issue
Block a user