From 68a825b7df9e2bb581086aad6435b083babdd287 Mon Sep 17 00:00:00 2001 From: DcruBro Date: Mon, 29 Dec 2025 18:02:42 +0100 Subject: [PATCH] test --- .gitignore | 3 +- .../columnlynx/common/libsodium_wrapper.hpp | 6 +--- .../common/net/session_registry.hpp | 2 +- src/client/main.cpp | 2 +- src/client/net/tcp/tcp_client.cpp | 27 ++++++++------ src/common/tcp_message_handler.cpp | 18 +++++++--- src/server/net/tcp/tcp_connection.cpp | 35 ++++++++++--------- 7 files changed, 53 insertions(+), 40 deletions(-) diff --git a/.gitignore b/.gitignore index da5e8e8..290af9a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ _deps CMakeUserPresets.json build/ -.vscode/ \ No newline at end of file +.vscode/ +.DS_Store diff --git a/include/columnlynx/common/libsodium_wrapper.hpp b/include/columnlynx/common/libsodium_wrapper.hpp index f5904b8..0685151 100644 --- a/include/columnlynx/common/libsodium_wrapper.hpp +++ b/include/columnlynx/common/libsodium_wrapper.hpp @@ -11,10 +11,6 @@ #include #include #include -#include -#include -#include -#include #include #include @@ -211,4 +207,4 @@ namespace ColumnLynx::Utils { std::array mXPublicKey; std::array mXPrivateKey; }; -} \ No newline at end of file +} diff --git a/include/columnlynx/common/net/session_registry.hpp b/include/columnlynx/common/net/session_registry.hpp index 762dc05..a8b1190 100644 --- a/include/columnlynx/common/net/session_registry.hpp +++ b/include/columnlynx/common/net/session_registry.hpp @@ -89,4 +89,4 @@ namespace ColumnLynx::Net { std::unordered_map mSessionIPs; std::unordered_map> mIPSessions; }; -} \ No newline at end of file +} diff --git a/src/client/main.cpp b/src/client/main.cpp index 1f73ac6..f700ec9 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -96,7 +96,7 @@ int main(int argc, char** argv) { }); //ioThread.join(); - log("Client connected to " + host + ":" + port); + log("Attempting connection to " + host + ":" + port); debug("Client connection flag: " + std::to_string(client->isConnected())); debug("Client handshake flag: " + std::to_string(client->isHandshakeComplete())); debug("isDone flag: " + std::to_string(done)); diff --git a/src/client/net/tcp/tcp_client.cpp b/src/client/net/tcp/tcp_client.cpp index dd90faa..75e78df 100644 --- a/src/client/net/tcp/tcp_client.cpp +++ b/src/client/net/tcp/tcp_client.cpp @@ -13,13 +13,22 @@ namespace ColumnLynx::Net::TCP { if (!ec) { asio::async_connect(mSocket, endpoints, [this, self](asio::error_code ec, const tcp::endpoint&) { - if (!NetHelper::isExpectedDisconnect(ec)) { + if (!ec) { mConnected = true; Utils::log("Client connected."); mHandler = std::make_shared(std::move(mSocket)); mHandler->onMessage([this](AnyMessageType type, const std::string& data) { mHandleMessage(static_cast(MessageHandler::toUint8(type)), data); }); + // Close only after peer FIN to avoid RSTs + mHandler->onDisconnect([this](const asio::error_code& ec) { + asio::error_code ec2; + if (mHandler) { + mHandler->socket().close(ec2); + } + mConnected = false; + Utils::log(std::string("Server disconnected: ") + ec.message()); + }); mHandler->start(); // Init connection handshake @@ -50,7 +59,9 @@ namespace ColumnLynx::Net::TCP { mStartHeartbeat(); } else { - Utils::error("Client connect failed: " + ec.message()); + if (!NetHelper::isExpectedDisconnect(ec)) { + Utils::error("Client connect failed: " + ec.message()); + } } }); } else { @@ -81,18 +92,14 @@ namespace ColumnLynx::Net::TCP { asio::error_code ec; mHeartbeatTimer.cancel(); - mHandler->socket().shutdown(tcp::socket::shutdown_both, ec); + // Half-close: stop sending, keep reading until peer FIN + mHandler->socket().shutdown(tcp::socket::shutdown_send, ec); if (ec) { Utils::error("Error during socket shutdown: " + ec.message()); } - mHandler->socket().close(ec); - if (ec) { - Utils::error("Error during socket close: " + ec.message()); - } - - mConnected = false; - Utils::log("Client disconnected."); + // Do not close immediately; rely on onDisconnect to finalize + Utils::log("Client initiated graceful disconnect (half-close)."); } } diff --git a/src/common/tcp_message_handler.cpp b/src/common/tcp_message_handler.cpp index 79cb1b7..ab09fcf 100644 --- a/src/common/tcp_message_handler.cpp +++ b/src/common/tcp_message_handler.cpp @@ -43,13 +43,19 @@ namespace ColumnLynx::Net::TCP { auto self = shared_from_this(); asio::async_read(mSocket, asio::buffer(mHeader), [this, self](asio::error_code ec, std::size_t) { - if (!NetHelper::isExpectedDisconnect(ec)) { + if (!ec) { mCurrentType = decodeMessageType(mHeader[0]); uint16_t len = (mHeader[1] << 8) | mHeader[2]; mReadBody(len); } else { - Utils::error("Header read failed: " + ec.message()); + if (!NetHelper::isExpectedDisconnect(ec)) { + Utils::error("Header read failed: " + ec.message()); + } + // Connection closed, trigger disconnect handler + if (mOnDisconnect) { + mOnDisconnect(ec); + } } } ); @@ -61,7 +67,7 @@ namespace ColumnLynx::Net::TCP { asio::async_read(mSocket, asio::buffer(mBody), [this, self](asio::error_code ec, std::size_t) { - if (!NetHelper::isExpectedDisconnect(ec)) { + if (!ec) { std::string payload(mBody.begin(), mBody.end()); // Dispatch based on message type @@ -71,8 +77,10 @@ namespace ColumnLynx::Net::TCP { mReadHeader(); // Keep listening } else { - Utils::error("Body read failed: " + ec.message()); - + if (!NetHelper::isExpectedDisconnect(ec)) { + Utils::error("Body read failed: " + ec.message()); + } + // Connection closed, trigger disconnect handler if (mOnDisconnect) { mOnDisconnect(ec); } diff --git a/src/server/net/tcp/tcp_connection.cpp b/src/server/net/tcp/tcp_connection.cpp index f6b28f6..6eaca97 100644 --- a/src/server/net/tcp/tcp_connection.cpp +++ b/src/server/net/tcp/tcp_connection.cpp @@ -11,8 +11,20 @@ namespace ColumnLynx::Net::TCP { }); mHandler->onDisconnect([this](const asio::error_code& ec) { - Utils::log("Client disconnected: " + mHandler->socket().remote_endpoint().address().to_string() + " - " + ec.message()); - disconnect(); + // Peer has closed; finalize locally without sending RST + std::string ip = mHandler->socket().remote_endpoint().address().to_string(); + Utils::log("Client disconnected: " + ip + " - " + ec.message()); + asio::error_code ec2; + mHandler->socket().close(ec2); + + SessionRegistry::getInstance().erase(mConnectionSessionID); + SessionRegistry::getInstance().deallocIP(mConnectionSessionID); + + Utils::log("Closed connection to " + ip); + + if (mOnDisconnect) { + mOnDisconnect(shared_from_this()); + } }); mHandler->start(); @@ -40,24 +52,13 @@ namespace ColumnLynx::Net::TCP { } mHeartbeatTimer.cancel(); asio::error_code ec; - mHandler->socket().shutdown(asio::ip::tcp::socket::shutdown_both, ec); + // Half-close: stop sending, keep reading until peer FIN + mHandler->socket().shutdown(asio::ip::tcp::socket::shutdown_send, ec); if (ec) { Utils::error("Error during socket shutdown: " + ec.message()); } - - mHandler->socket().close(ec); - if (ec) { - Utils::error("Error during socket close: " + ec.message()); - } - - SessionRegistry::getInstance().erase(mConnectionSessionID); - SessionRegistry::getInstance().deallocIP(mConnectionSessionID); - - Utils::log("Closed connection to " + ip); - - if (mOnDisconnect) { - mOnDisconnect(shared_from_this()); - } + // Do not close immediately; final cleanup happens in onDisconnect + Utils::log("Initiated graceful disconnect (half-close) to " + ip); } uint64_t TCPConnection::getSessionID() const {