]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
socket: enable port sharing on Linux
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 23 Mar 2020 10:34:02 +0000 (11:34 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 24 Mar 2020 15:29:33 +0000 (16:29 +0100)
On Linux, enable the SO_REUSEPORT option on sockets bound to a port in
order to support load balancing with multiple chronyd instances
(configured to not adjust the system clock).

The IP_FREEBIND option already allowed different instances to bind to
the same address and port, but only one was actually receiving packets.

As the instances don't share their state, sharing the NTP port doesn't
work well with the interleaved mode, symmetric mode, and rate limiting.

Sharing the NTS-KE port will not work until the server keys can be
derived from a shared key.

socket.c
sys_linux.c

index 0a248797cacc87d94766dcafe56cd7b86327e5f0..3c1ffd334ff592e439a8b1d4042d67df350eb4af 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -342,6 +342,14 @@ bind_ip_address(int sock_fd, IPSockAddr *addr, int flags)
   if (addr->port > 0 && !SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1))
     ;
 
+#if defined(LINUX) && defined(SO_REUSEPORT)
+  /* Allow multiple instances to bind to the same port in order to enable load
+     balancing.  Don't enable this option on non-Linux systems as it has
+     a slightly different meaning there (with some important implications). */
+  if (addr->port > 0 && !SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_REUSEPORT, 1))
+    ;
+#endif
+
 #ifdef IP_FREEBIND
   /* Allow binding to an address that doesn't exist yet */
   if (!SCK_SetIntOption(sock_fd, IPPROTO_IP, IP_FREEBIND, 1))
index 09b96a96e7af5b7421801ab16bb94a9845ec58ff..1f08e6441e6a7ff9a5e3ec8c4e254897743a1861 100644 (file)
@@ -523,6 +523,9 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_SystemCallContext context)
     { SOL_IPV6, IPV6_V6ONLY }, { SOL_IPV6, IPV6_RECVPKTINFO },
 #endif
     { SOL_SOCKET, SO_BROADCAST }, { SOL_SOCKET, SO_REUSEADDR },
+#ifdef SO_REUSEPORT
+    { SOL_SOCKET, SO_REUSEPORT },
+#endif
     { SOL_SOCKET, SO_TIMESTAMP }, { SOL_SOCKET, SO_TIMESTAMPNS },
 #ifdef HAVE_LINUX_TIMESTAMPING
     { SOL_SOCKET, SO_SELECT_ERR_QUEUE }, { SOL_SOCKET, SO_TIMESTAMPING },