syslogd listen keep alive

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

syslogd listen keep alive

Alexander Bluhm
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 | Threaded
Open this post in threaded view
|

Re: syslogd listen keep alive

Todd C. Miller-3
On Mon, 14 Sep 2020 21:49:07 +0200, Alexander Bluhm wrote:

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

OK millert@

 - todd

Reply | Threaded
Open this post in threaded view
|

Re: syslogd listen keep alive

Theo de Raadt-2
In reply to this post by Alexander Bluhm
Excellent!


Alexander Bluhm <[hidden email]> wrote:

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