From 7cb8b242668dbadacc3886b389962a1b8756bdac Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Mon, 18 Nov 2024 15:30:06 +0000 Subject: [PATCH] Allow reuse address when firing up the ros2cli daemon. Especially in tests where the daemon is being repeatedly created and destroyed, it can take some time for the kernel to actually allow the address to be rebinded (even after the old process has exited). This can lead to some situations where we fail to spawn the daemon. To fix this, set "allow_reuse_address" inside the LocalXMLRPCServer, which will set SO_REUSADDR on the socket. Signed-off-by: Chris Lalancette --- ros2cli/ros2cli/xmlrpc/local_server.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ros2cli/ros2cli/xmlrpc/local_server.py b/ros2cli/ros2cli/xmlrpc/local_server.py index 9e3e9e476..c439cef48 100644 --- a/ros2cli/ros2cli/xmlrpc/local_server.py +++ b/ros2cli/ros2cli/xmlrpc/local_server.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import socket import struct # Import SimpleXMLRPCRequestHandler to re-export it. @@ -32,7 +33,15 @@ def get_local_ipaddrs(): class LocalXMLRPCServer(SimpleXMLRPCServer): - allow_reuse_address = False + # Allow re-binding even if another server instance was recently bound (i.e. we are still in + # TCP TIME_WAIT). This is already the default behavior on Windows, and further SO_REUSEADDR can + # lead to undefined behavior on Windows; see + # https://learn.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse. # noqa + # So we don't set the option for Windows. + if os.name == 'nt': + allow_reuse_address = False + else: + allow_reuse_address = True def server_bind(self): # Prevent listening socket from lingering in TIME_WAIT state after close()