From b8b751a9323b920a79085d1398af4df76dcc23a8 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Mon, 23 Mar 2020 11:34:02 +0100 Subject: [PATCH] socket: enable port sharing on Linux 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 | 8 ++++++++ sys_linux.c | 3 +++ 2 files changed, 11 insertions(+) diff --git a/socket.c b/socket.c index 0a24879..3c1ffd3 100644 --- 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)) diff --git a/sys_linux.c b/sys_linux.c index 09b96a9..1f08e64 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -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 },