Hi,

A while ago dhill@ pointed out that syslogd TCP sockets will stay
open forever if a client aborts the connection silently.  As syslogd
does not write anything into incoming connections, it will not
recognize failure and the socket will stay forever.

Setting TCP keep alive on the listen socket will prevent that.  Note
that outgoing connections don't need it as syslogd will write data
into them.

After keep alive timeout you get this:

syslogd[51331]: tcp logger "10.188.74.74:32769" connection error: Operation 
timed out
syslogd[51331]: tls logger "10.188.74.74:15557" connection error: read failed: 
error:02FFF03C:system library:func(4095):Operation timed out

ok?

bluhm

Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.263
diff -u -p -r1.263 syslogd.c
--- usr.sbin/syslogd/syslogd.c  25 May 2020 10:38:32 -0000      1.263
+++ usr.sbin/syslogd/syslogd.c  14 Sep 2020 15:09:14 -0000
@@ -354,6 +354,7 @@ int socket_bind(const char *, const char
 int    unix_socket(char *, int, mode_t);
 void   double_sockbuf(int, int, int);
 void   set_sockbuf(int);
+void   set_keepalive(int);
 void   tailify_replytext(char *, int);
 
 int
@@ -979,8 +980,10 @@ socket_bind(const char *proto, const cha
                }
                if (!shutread && res->ai_protocol == IPPROTO_UDP)
                        double_sockbuf(*fdp, SO_RCVBUF, 0);
-               else if (res->ai_protocol == IPPROTO_TCP)
+               else if (res->ai_protocol == IPPROTO_TCP) {
                        set_sockbuf(*fdp);
+                       set_keepalive(*fdp);
+               }
                reuseaddr = 1;
                if (setsockopt(*fdp, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
                    sizeof(reuseaddr)) == -1) {
@@ -3104,6 +3107,15 @@ set_sockbuf(int fd)
                log_warn("setsockopt sndbufsize %d", size);
        if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) == -1)
                log_warn("setsockopt rcvbufsize %d", size);
+}
+
+void
+set_keepalive(int fd)
+{
+       int val = 1;
+
+       if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1)
+               log_warn("setsockopt keepalive %d", val);
 }
 
 void

Reply via email to