From 75f71df7a878e28a5d44cc6bee3b47987a07e018 Mon Sep 17 00:00:00 2001 From: Tyler Rau Date: Thu, 16 May 2024 11:27:48 -0700 Subject: [PATCH] Fix TCPSocket constructor exception safety This commit fixes closing a TCPSocket's raw socket if something goes wrong in the constructor. Presently if the socket gets opened but something else goes wrong then the file descriptor(FD) is left dangling and can quickly exhaust the system FD limit --- src/sockets/TCPSocket.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/sockets/TCPSocket.cpp b/src/sockets/TCPSocket.cpp index bbceaac..793e7d4 100644 --- a/src/sockets/TCPSocket.cpp +++ b/src/sockets/TCPSocket.cpp @@ -43,6 +43,29 @@ namespace eipScanner { } #endif + //once _sockedFd turns out to be a value not less than zero then + //we have to free it via a shutdown/close pair. Normally the destructor + //for the TCPSocket object would do that; however if a throw happens in this + //constructor then the destructor isn't called. Therefore we need to cause + //cleanup to happen ourselves in that case. + class socket_scope_cleanup { + private: + bool should_cleanup = true; + TCPSocket* socket_; + public: + socket_scope_cleanup(TCPSocket* socket):socket_(socket){} + ~socket_scope_cleanup() { + if(should_cleanup) { + Logger(LogLevel::DEBUG) << "Close TCP socket fd=" << _sockedFd; + socket_->Shutdown(); + socket_->Close(); + } + } + void do_not_cleanup() { + should_cleanup = false; + } + } socket_scope_cleanup_instance{this}; + // Set non-blocking #if defined(__unix__) || defined(__APPLE__) auto arg = fcntl(_sockedFd, F_GETFL, NULL);