summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2013-12-14 00:25:57 +0000
committerian <ian@FreeBSD.org>2013-12-14 00:25:57 +0000
commit3360970b016395e930ab2a2e9db97174e387e337 (patch)
tree539532d4023a2e31f3573e7451d2a09eda8ab573 /usr.sbin
parent2c66a0246a05805dc6d5b3916af710b9924d168c (diff)
downloadFreeBSD-src-3360970b016395e930ab2a2e9db97174e387e337.zip
FreeBSD-src-3360970b016395e930ab2a2e9db97174e387e337.tar.gz
MFC r258076, r258077:
This fixes 3 problems in syslogd related to sizing receive buffers... - A call was misplaced at the wrong level of nested if blocks, so that the buffers for unix domain sockets (/dev/log, /dev/klog) were never increased at all; they remained at a way-too-small default size of 4096. - The function that was supposed to double the size of the buffer sometimes did nothing, and sometimes installed a wildly-wrong buffer size (either too large or too small) due to an unitialized 'slen' variable passed to getsockopt(). Most often it doubled the UDP buffers from 40k to 80k because accidentally there would be harmless stack garbage in the unitialized variables. - The whole concept of blindly doubling a socket's buffer size without knowing what size it started at is a design flaw that has to be called a bug. If the double_rbuf() function had worked at all (I.E., if the other two bugs didn't exist) this would lead to UDP sockets having an 80k buffer while unix dgram sockets get an 8k buffer. There's nothing about the problem being solved that requires larger buffers for UDP than for unix dgram sockets -- the buffering requirements are the same regardless of socket type. This change renames the double_rbuf() function to increase_rbuf() and increases the buffer size on all types of sockets to 80k. 80k was chosen only because it appears to be the size the original change was shooting for, and it certainly seems to be reasonably large (I might have picked 64k in the absence of any historical guidance). Add ENETUNREACH and EADDRNOTAVAIL to the list of errors that are potentially transient and shouldn't result in closing the socket and giving up forever.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/syslogd/syslogd.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
index 8fc2678..60c74d1 100644
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
#define DEFSPRI (LOG_KERN|LOG_CRIT)
#define TIMERINTVL 30 /* interval for checking flush, mark */
#define TTYMSGTIME 1 /* timeout passed to ttymsg */
+#define RCVBUF_MINSIZE (80 * 1024) /* minimum size of dgram rcv buffer */
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -336,7 +337,7 @@ static void unmapped(struct sockaddr *);
static void wallmsg(struct filed *, struct iovec *, const int iovlen);
static int waitdaemon(int, int, int);
static void timedout(int);
-static void double_rbuf(int);
+static void increase_rcvbuf(int);
int
main(int argc, char *argv[])
@@ -547,8 +548,8 @@ main(int argc, char *argv[])
STAILQ_REMOVE(&funixes, fx, funix, next);
continue;
}
- double_rbuf(fx->s);
}
+ increase_rcvbuf(fx->s);
}
if (SecureMode <= 1)
finet = socksetup(family, bindhostname);
@@ -1241,8 +1242,10 @@ fprintlog(struct filed *f, int flags, const char *msg)
switch (errno) {
case ENOBUFS:
case ENETDOWN:
+ case ENETUNREACH:
case EHOSTUNREACH:
case EHOSTDOWN:
+ case EADDRNOTAVAIL:
break;
/* case EBADF: */
/* case EACCES: */
@@ -1253,7 +1256,7 @@ fprintlog(struct filed *f, int flags, const char *msg)
/* case ENOBUFS: */
/* case ECONNREFUSED: */
default:
- dprintf("removing entry\n");
+ dprintf("removing entry: errno=%d\n", e);
f->f_type = F_UNUSED;
break;
}
@@ -2720,7 +2723,7 @@ socksetup(int af, char *bindhostname)
}
if (!SecureMode)
- double_rbuf(*s);
+ increase_rcvbuf(*s);
}
(*socks)++;
@@ -2741,12 +2744,16 @@ socksetup(int af, char *bindhostname)
}
static void
-double_rbuf(int fd)
+increase_rcvbuf(int fd)
{
- socklen_t slen, len;
+ socklen_t len, slen;
+
+ slen = sizeof(len);
if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, &slen) == 0) {
- len *= 2;
- setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, slen);
+ if (len < RCVBUF_MINSIZE) {
+ len = RCVBUF_MINSIZE;
+ setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
+ }
}
}
OpenPOWER on IntegriCloud