diff --git a/src/lib/base/EventTypes.h b/src/lib/base/EventTypes.h index ae76dfc84..b86395c90 100644 --- a/src/lib/base/EventTypes.h +++ b/src/lib/base/EventTypes.h @@ -91,6 +91,11 @@ enum class EventTypes : uint32_t /// This event is sent whenever a server accepts a client. ClientListenerAccepted, + /** This event is sent whenever a client disconnects/errors out before the connection + is fully accepted. + */ + ClientListenerDisconnectedOnAccept, + /** This event is sent when the client has completed the initial handshake. Until it is sent, the client is not fully connected. */ diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index d56f01a62..65203ea9b 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -693,6 +693,7 @@ ISocketMultiplexerJob *SecureSocket::serviceAccept(ISocketMultiplexerJob *const, #endif // If status < 0, error happened if (status < 0) { + sendEvent(EventTypes::ClientListenerDisconnectedOnAccept); return nullptr; } diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp index 1ffee6184..583c1c351 100644 --- a/src/lib/server/ClientListener.cpp +++ b/src/lib/server/ClientListener.cpp @@ -138,6 +138,14 @@ void ClientListener::handleClientConnecting() [this, rawSocketPointer](const auto &) { handleClientAccepted(rawSocketPointer); } ); + m_events->addHandler( + EventTypes::ClientListenerDisconnectedOnAccept, rawSocketPointer->getEventTarget(), + [this, rawSocketPointer](const auto &) { + LOG_DEBUG("disconnected client before accept"); + removeClientSocket(rawSocketPointer); + } + ); + // When using non SSL, server accepts clients immediately, while SSL // has to call secure accept which may require retry if (m_securityLevel == SecurityLevel::PlainText) { @@ -205,14 +213,20 @@ void ClientListener::handleClientDisconnected(ClientProxy *client) // we know which socket we no longer need auto *socket = static_cast(client->getStream()); delete client; - m_clientSockets.erase(socket); - delete socket; + removeClientSocket(socket); break; } } } +void ClientListener::removeClientSocket(IDataSocket *socket) +{ + m_clientSockets.erase(socket); + m_events->removeHandlers(socket->getEventTarget()); + delete socket; +} + void ClientListener::cleanupListenSocket() { delete m_listen; diff --git a/src/lib/server/ClientListener.h b/src/lib/server/ClientListener.h index 17160e76d..a2be0573f 100644 --- a/src/lib/server/ClientListener.h +++ b/src/lib/server/ClientListener.h @@ -71,6 +71,7 @@ private: void handleUnknownClient(ClientProxyUnknown *unknownClient); void handleClientDisconnected(ClientProxy *client); + void removeClientSocket(IDataSocket *socket); void cleanupListenSocket(); void cleanupClientSockets(); void start();