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.
This commit is contained in:
Maya 2023-04-19 03:01:21 +01:00
parent fac4973329
commit ba7838c04e

View File

@ -41,7 +41,13 @@ class HDLC():
return data return data
class ThreadingTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): 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): class LocalClientInterface(Interface):
RECONNECT_WAIT = 3 RECONNECT_WAIT = 3
@ -299,7 +305,6 @@ class LocalServerInterface(Interface):
address = (self.bind_ip, self.bind_port) address = (self.bind_ip, self.bind_port)
ThreadingTCPServer.allow_reuse_address = True
self.server = ThreadingTCPServer(address, handlerFactory(self.incoming_connection)) self.server = ThreadingTCPServer(address, handlerFactory(self.incoming_connection))
thread = threading.Thread(target=self.server.serve_forever) thread = threading.Thread(target=self.server.serve_forever)