From 26affe6305dbbf8a02c0672ff2d6cb2649d251da Mon Sep 17 00:00:00 2001 From: Yan Date: Fri, 12 Jun 2026 11:47:40 -0700 Subject: [PATCH] SocketServer: close _serverFd exactly once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SocketServer::stop() closed _serverFd but never cleared it, and stop() runs again from both ~WebSocketServer() and ~SocketServer(), so every teardown closed the same fd number two or three times. If another thread opens a descriptor between those closes, the kernel reuses the number and the stale close destroys it — observed as intermittent process aborts ("Unexpected error 9 on netlink descriptor", glibc's getaddrinfo netlink probe) when a DNS lookup raced a server teardown. Close the fd once and set it to -1, in stop() and in the listen() error paths. Co-Authored-By: Claude Fable 5 --- ixwebsocket/IXSocketServer.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ixwebsocket/IXSocketServer.cpp b/ixwebsocket/IXSocketServer.cpp index 790cfdf5..bf9d20aa 100644 --- a/ixwebsocket/IXSocketServer.cpp +++ b/ixwebsocket/IXSocketServer.cpp @@ -95,6 +95,7 @@ namespace ix << "at address " << _host << ":" << _port << " : " << strerror(Socket::getErrno()); Socket::closeSocket(_serverFd); + _serverFd = -1; return std::make_pair(false, ss.str()); } @@ -113,6 +114,7 @@ namespace ix << strerror(Socket::getErrno()); Socket::closeSocket(_serverFd); + _serverFd = -1; return std::make_pair(false, ss.str()); } @@ -125,6 +127,7 @@ namespace ix << strerror(Socket::getErrno()); Socket::closeSocket(_serverFd); + _serverFd = -1; return std::make_pair(false, ss.str()); } } @@ -143,6 +146,7 @@ namespace ix << strerror(Socket::getErrno()); Socket::closeSocket(_serverFd); + _serverFd = -1; return std::make_pair(false, ss.str()); } @@ -155,6 +159,7 @@ namespace ix << strerror(Socket::getErrno()); Socket::closeSocket(_serverFd); + _serverFd = -1; return std::make_pair(false, ss.str()); } } @@ -169,6 +174,7 @@ namespace ix << "at address " << _host << ":" << _port << " : " << strerror(Socket::getErrno()); Socket::closeSocket(_serverFd); + _serverFd = -1; return std::make_pair(false, ss.str()); } @@ -231,7 +237,16 @@ namespace ix } _conditionVariable.notify_one(); - Socket::closeSocket(_serverFd); + + // stop() runs again from ~WebSocketServer() and ~SocketServer(), so + // close the listening fd exactly once: a second close of the stale + // number would destroy whatever descriptor another thread has since + // opened with it. + if (_serverFd != -1) + { + Socket::closeSocket(_serverFd); + _serverFd = -1; + } } void SocketServer::setConnectionStateFactory(