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).

PR:		160433
Submitted by:	me, in 2011.
This commit is contained in:
Ian Lepore 2013-11-13 01:01:15 +00:00
parent 565bbb8698
commit 6a3e86ff22
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=258076

View File

@ -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);
@ -2720,7 +2721,7 @@ socksetup(int af, char *bindhostname)
}
if (!SecureMode)
double_rbuf(*s);
increase_rcvbuf(*s);
}
(*socks)++;
@ -2741,12 +2742,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));
}
}
}