]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
set TCP_NODELAY by default
authorAlan T. DeKok <aland@freeradius.org>
Mon, 15 Apr 2024 15:59:50 +0000 (11:59 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 15 Apr 2024 15:59:50 +0000 (11:59 -0400)
src/lib/bio/fd.h
src/lib/bio/fd_open.c

index aee79b7944e45e796e736f9357cf984af31e624c..7c695251c409536b2789d34acdc02b71e13d741d 100644 (file)
@@ -98,6 +98,7 @@ typedef struct {
        int             flags;          //!< O_RDONLY, etc.
 
        bool            async;          //!< is it async
+       bool            tcp_delay;      //!< We do tcp_nodelay by default.
 } fr_bio_fd_config_t;
 
 /** Run-time status of the socket.
index 1f93fa2f9865bad7453d68e5b985580abd46ab4c..aae05ac7a8938e06de8d256e6acc9a29d83c2834 100644 (file)
 #include <net/if.h>
 #include <fcntl.h>
 #include <libgen.h>
+#include <netinet/tcp.h>
 
 /** Initialize common datagram information
  *
  */
-static int fr_bio_fd_common_tcp(int fd, UNUSED fr_socket_t const *sock, UNUSED fr_bio_fd_config_t const *cfg)
+static int fr_bio_fd_common_tcp(int fd, UNUSED fr_socket_t const *sock, fr_bio_fd_config_t const *cfg)
 {
        int on = 1;
 
 #ifdef SO_KEEPALIVE
+       /*
+        *      TCP keepalives are always a good idea.  Too many people put firewalls between critical
+        *      systems, and then the firewalls drop live TCP streams.
+        */
        if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) {
                fr_strerror_printf("Failed setting SO_KEEPALIVE: %s", fr_syserror(errno));
                return -1;
        }
 #endif
 
+#ifdef TCP_NODELAY
+       /*
+        *      Add some defines for *BSD, and Solaris systems.
+        */
+#  if !defined(SOL_TCP) && defined(IPPROTO_TCP)
+#    define SOL_TCP IPPROTO_TCP
+#  endif
+
+       /*
+        *      Also set TCP_NODELAY, to force the data to be written quickly.
+        *
+        *      We buffer full packets in memory before we write them, so there's no reason for the kernel to
+        *      sit around waiting for more data from us.
+        */
+       if (!cfg->tcp_delay) {
+               if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) {
+                       fr_strerror_printf("Failed setting TCP_NODELAY: %s", fr_syserror(errno));
+                       return -1;
+               }
+       }
+#endif
+
        return 0;
 }