Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Dec 2013 00:25:58 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r259368 - stable/10/usr.sbin/syslogd
Message-ID:  <201312140025.rBE0Pwmx098797@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sat Dec 14 00:25:57 2013
New Revision: 259368
URL: http://svnweb.freebsd.org/changeset/base/259368

Log:
  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.

Modified:
  stable/10/usr.sbin/syslogd/syslogd.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/syslogd/syslogd.c
==============================================================================
--- stable/10/usr.sbin/syslogd/syslogd.c	Sat Dec 14 00:25:25 2013	(r259367)
+++ stable/10/usr.sbin/syslogd/syslogd.c	Sat Dec 14 00:25:57 2013	(r259368)
@@ -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, co
 				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, co
 				/* 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));
+		}
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312140025.rBE0Pwmx098797>