From 2c7659ec930277981b6333b5b3aff7840d11933c Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Sun, 25 Oct 2026 18:51:51 +0100 Subject: Decouple config parsing from binding and worker spawning * Options are parsed now into a listener description list before binding them at once and starting the workers later * UDP workers can now be configured per connection * socket reuse is now done more sensibly, mcast sockets always reused * Hold-off logic after spawning udp workers removed --- ot_socket.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'ot_socket.c') diff --git a/ot_socket.c b/ot_socket.c index e26ad52..84020ca 100644 --- a/ot_socket.c +++ b/ot_socket.c @@ -15,8 +15,6 @@ #include "ot_ip.h" #include "ot_socket.h" -int g_socket_reuseport; - static void sockaddr_from_ip(struct sockaddr_in6 *sa, const ot_ip6 ip, uint16_t port) { memset(sa, 0, sizeof(*sa)); sa->sin6_family = AF_INET6; @@ -75,37 +73,43 @@ static int socket_v6(int type) { return s; } -static int socket_bind_v6(int s, const ot_ip6 ip, uint16_t port) { - struct sockaddr_in6 sa; - int one = 1; +/* The only place in the tree that needs to know what a kernel calls this */ +static void socket_set_sharing(int s, socket_sharing sharing) { + int one = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); #ifdef SO_REUSEPORT - if (g_socket_reuseport) + if (sharing == SOCKET_SHARED) setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)); #endif +} + +static int socket_bind_v6(int s, const ot_ip6 ip, uint16_t port, socket_sharing sharing) { + struct sockaddr_in6 sa; + + socket_set_sharing(s, sharing); sockaddr_from_ip(&sa, ip, port); return bind(s, (struct sockaddr *)&sa, sizeof(sa)); } -int socket_tcp_listen(const ot_ip6 ip, uint16_t port) { +int socket_tcp_listen(const ot_ip6 ip, uint16_t port, socket_sharing sharing) { int s = socket_v6(SOCK_STREAM); if (s == -1) return -1; - if (socket_bind_v6(s, ip, port) == -1 || listen(s, SOMAXCONN) == -1) + if (socket_bind_v6(s, ip, port, sharing) == -1 || listen(s, SOMAXCONN) == -1) return close_and_fail(s); return s; } -int socket_udp_bind(const ot_ip6 ip, uint16_t port) { +int socket_udp_bind(const ot_ip6 ip, uint16_t port, socket_sharing sharing) { int s = socket_v6(SOCK_DGRAM); if (s == -1) return -1; - if (socket_bind_v6(s, ip, port) == -1) + if (socket_bind_v6(s, ip, port, sharing) == -1) return close_and_fail(s); return s; @@ -117,7 +121,7 @@ int socket_tcp_connect(const ot_ip6 srcip, uint16_t srcport, const ot_ip6 dstip, if (s == -1) return -1; - if (socket_bind_v6(s, srcip, srcport) == -1) + if (socket_bind_v6(s, srcip, srcport, SOCKET_EXCLUSIVE) == -1) return close_and_fail(s); sockaddr_from_ip(&sa, dstip, dstport); @@ -187,18 +191,16 @@ static void sockaddr4_from_ip(struct sockaddr_in *sa, const ot_ip6 ip, uint16_t memcpy(&sa->sin_addr, ip + sizeof(ip_v4mapped_prefix), 4); } +/* A multicast group is meant to have several listeners, so these are always + shared */ static int socket_v4_bind(const ot_ip6 ip, uint16_t port) { struct sockaddr_in sa; - int s, one = 1; + int s; if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return -1; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); -#ifdef SO_REUSEPORT - if (g_socket_reuseport) - setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)); -#endif + socket_set_sharing(s, SOCKET_SHARED); sockaddr4_from_ip(&sa, ip, port); if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) == -1) -- cgit v1.3