From ba7838c04e959e96c425d32c41de044fddab3f19 Mon Sep 17 00:00:00 2001 From: Maya Date: Wed, 19 Apr 2023 03:01:21 +0100 Subject: [PATCH] Use SO_EXCLUSIVEADDRUSE instead of SO_REUSEADDR on Windows. On Linux, SO_REUSEADDR is used so that a socket in TIME-WAIT state can be rebound after a listening process is restarted. It does not allow two processes to listen on the exact same (addr, port) combination. However, on Windows, it does, and SO_EXCLUSIVEADDRUSE is required to reproduce the Linux behavior. Reticulum relies on an error being returned by bind() that reuses the same (addr, port) combination as another process to detect whether there is a shared instance already running. Setting SO_EXCLUSIVEADDRUSE makes this detection process work on Windows as well. --- RNS/Interfaces/LocalInterface.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/RNS/Interfaces/LocalInterface.py b/RNS/Interfaces/LocalInterface.py index 937a5d3..1a37e64 100644 --- a/RNS/Interfaces/LocalInterface.py +++ b/RNS/Interfaces/LocalInterface.py @@ -41,7 +41,13 @@ class HDLC(): return data class ThreadingTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): - pass + def server_bind(self): + if sys.platform == 'win32': + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) + else: + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.socket.bind(self.server_address) + self.server_address = self.socket.getsockname() class LocalClientInterface(Interface): RECONNECT_WAIT = 3 @@ -299,7 +305,6 @@ class LocalServerInterface(Interface): address = (self.bind_ip, self.bind_port) - ThreadingTCPServer.allow_reuse_address = True self.server = ThreadingTCPServer(address, handlerFactory(self.incoming_connection)) thread = threading.Thread(target=self.server.serve_forever)