Compare commits
17 Commits
dev
...
31cb3d0a02
| Author | SHA1 | Date | |
|---|---|---|---|
| 31cb3d0a02 | |||
| 0299b03d9c | |||
| 204f89006f | |||
| 57d260976c | |||
| 4fa26d51d0 | |||
| e1118ccafe | |||
| 00f72e1a64 | |||
| 3cd99243ad | |||
| 8f536abe77 | |||
| 3eadd41a00 | |||
| 714aa52f98 | |||
| a2ecc589f8 | |||
| 640a751f9b | |||
| a08dba5b59 | |||
| 4ba59fb23f | |||
| 9e5e728438 | |||
| d20bee9e60 |
@@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
# If MAJOR is 0, and MINOR > 0, Version is BETA
|
||||
|
||||
project(ColumnLynx
|
||||
VERSION 1.1.1
|
||||
VERSION 1.1.0
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <columnlynx/common/utils.hpp>
|
||||
#include <columnlynx/common/libsodium_wrapper.hpp>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
@@ -90,8 +89,8 @@ namespace ColumnLynx::Net::TCP {
|
||||
|
||||
// TODO: Move ptrs to smart ptrs
|
||||
|
||||
std::atomic<bool> mConnected{false};
|
||||
std::atomic<bool> mHandshakeComplete{false};
|
||||
bool mConnected = false;
|
||||
bool mHandshakeComplete = false;
|
||||
tcp::resolver mResolver;
|
||||
tcp::socket mSocket;
|
||||
std::shared_ptr<MessageHandler> mHandler;
|
||||
|
||||
@@ -39,6 +39,6 @@ namespace ColumnLynx::Net::TCP {
|
||||
std::array<uint8_t, 3> mHeader{}; // [type][lenHigh][lenLow]
|
||||
std::vector<uint8_t> mBody;
|
||||
std::function<void(AnyMessageType, std::string)> mOnMessage;
|
||||
std::function<void(const asio::error_code&)> mOnDisconnect;
|
||||
std::function<void(asio::error_code&)> mOnDisconnect;
|
||||
};
|
||||
}
|
||||
@@ -14,25 +14,19 @@ namespace ColumnLynx::Net::TCP {
|
||||
asio::async_connect(mSocket, endpoints,
|
||||
[this, self](asio::error_code ec, const tcp::endpoint&) {
|
||||
if (!ec) {
|
||||
mConnected.store(true, std::memory_order_relaxed);
|
||||
mConnected = true;
|
||||
Utils::log("Client connected.");
|
||||
mHandler = std::make_shared<MessageHandler>(std::move(mSocket));
|
||||
mHandler->onMessage([weakSelf = weak_from_this()](AnyMessageType type, const std::string& data) {
|
||||
if (auto self = weakSelf.lock()) {
|
||||
self->mHandleMessage(static_cast<ServerMessageType>(MessageHandler::toUint8(type)), data);
|
||||
}
|
||||
mHandler->onMessage([this](AnyMessageType type, const std::string& data) {
|
||||
mHandleMessage(static_cast<ServerMessageType>(MessageHandler::toUint8(type)), data);
|
||||
});
|
||||
// Close only after peer FIN to avoid RSTs
|
||||
mHandler->onDisconnect([weakSelf = weak_from_this()](const asio::error_code& ec) {
|
||||
auto self = weakSelf.lock();
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
mHandler->onDisconnect([this](const asio::error_code& ec) {
|
||||
asio::error_code ec2;
|
||||
if (self->mHandler) {
|
||||
self->mHandler->socket().close(ec2);
|
||||
if (mHandler) {
|
||||
mHandler->socket().close(ec2);
|
||||
}
|
||||
self->mConnected.store(false, std::memory_order_relaxed);
|
||||
mConnected = false;
|
||||
Utils::log(std::string("Server disconnected: ") + ec.message());
|
||||
});
|
||||
mHandler->start();
|
||||
@@ -80,7 +74,7 @@ namespace ColumnLynx::Net::TCP {
|
||||
}
|
||||
|
||||
void TCPClient::sendMessage(ClientMessageType type, const std::string& data) {
|
||||
if (!mConnected.load(std::memory_order_relaxed)) {
|
||||
if (!mConnected) {
|
||||
Utils::error("Cannot send message, client not connected.");
|
||||
return;
|
||||
}
|
||||
@@ -93,7 +87,7 @@ namespace ColumnLynx::Net::TCP {
|
||||
}
|
||||
|
||||
void TCPClient::disconnect(bool echo) {
|
||||
if (mConnected.load(std::memory_order_relaxed) && mHandler) {
|
||||
if (mConnected && mHandler) {
|
||||
if (echo) {
|
||||
mHandler->sendMessage(ClientMessageType::GRACEFUL_DISCONNECT, "Goodbye");
|
||||
}
|
||||
@@ -113,17 +107,17 @@ namespace ColumnLynx::Net::TCP {
|
||||
}
|
||||
|
||||
bool TCPClient::isHandshakeComplete() const {
|
||||
return mHandshakeComplete.load(std::memory_order_relaxed);
|
||||
return mHandshakeComplete;
|
||||
}
|
||||
|
||||
bool TCPClient::isConnected() const {
|
||||
return mConnected.load(std::memory_order_relaxed);
|
||||
return mConnected;
|
||||
}
|
||||
|
||||
void TCPClient::mStartHeartbeat() {
|
||||
auto self = shared_from_this();
|
||||
mHeartbeatTimer.expires_after(std::chrono::seconds(5));
|
||||
mHeartbeatTimer.async_wait([self](const asio::error_code& ec) {
|
||||
mHeartbeatTimer.async_wait([this, self](const asio::error_code& ec) {
|
||||
if (ec == asio::error::operation_aborted) {
|
||||
return; // Timer was cancelled
|
||||
}
|
||||
@@ -136,11 +130,9 @@ namespace ColumnLynx::Net::TCP {
|
||||
|
||||
// Close sockets forcefully, server is dead
|
||||
asio::error_code ec;
|
||||
if (self->mHandler) {
|
||||
self->mHandler->socket().shutdown(tcp::socket::shutdown_both, ec);
|
||||
self->mHandler->socket().close(ec);
|
||||
}
|
||||
self->mConnected.store(false, std::memory_order_relaxed);
|
||||
mHandler->socket().shutdown(tcp::socket::shutdown_both, ec);
|
||||
mHandler->socket().close(ec);
|
||||
mConnected = false;
|
||||
|
||||
ClientSession::getInstance().setAESKey({}); // Clear AES key with all zeros
|
||||
ClientSession::getInstance().setSessionID(0);
|
||||
@@ -269,7 +261,7 @@ namespace ColumnLynx::Net::TCP {
|
||||
mTun->configureIP(clientIP, serverIP, prefixLen, mtu);
|
||||
}
|
||||
|
||||
mHandshakeComplete.store(true, std::memory_order_relaxed);
|
||||
mHandshakeComplete = true;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -284,13 +276,13 @@ namespace ColumnLynx::Net::TCP {
|
||||
break;
|
||||
case ServerMessageType::GRACEFUL_DISCONNECT:
|
||||
Utils::log("Server is disconnecting: " + data);
|
||||
if (mConnected.load(std::memory_order_relaxed)) { // Prevent Recursion
|
||||
if (mConnected) { // Prevent Recursion
|
||||
disconnect(false);
|
||||
}
|
||||
break;
|
||||
case ServerMessageType::KILL_CONNECTION:
|
||||
Utils::warn("Server is killing the connection: " + data);
|
||||
if (mConnected.load(std::memory_order_relaxed)) {
|
||||
if (mConnected) {
|
||||
disconnect(false);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -85,15 +85,11 @@ namespace ColumnLynx::Net {
|
||||
void SessionRegistry::lockIP(uint32_t sessionID, uint32_t ip) {
|
||||
std::unique_lock lock(mMutex);
|
||||
mSessionIPs[sessionID] = ip;
|
||||
|
||||
auto it = mSessions.find(sessionID);
|
||||
if (it == mSessions.end() || !it->second) {
|
||||
Utils::warn("SessionRegistry::lockIP called for unknown session " + std::to_string(sessionID));
|
||||
mSessionIPs.erase(sessionID);
|
||||
return;
|
||||
}
|
||||
|
||||
mIPSessions[ip] = it->second;
|
||||
|
||||
/*if (mIPSessions.find(sessionID) == mIPSessions.end()) {
|
||||
Utils::debug("yikes");
|
||||
}*/
|
||||
mIPSessions[ip] = mSessions.find(sessionID)->second;
|
||||
}
|
||||
|
||||
void SessionRegistry::deallocIP(uint32_t sessionID) {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <columnlynx/common/net/tcp/tcp_message_handler.hpp>
|
||||
#include <columnlynx/common/net/tcp/net_helper.hpp>
|
||||
#include <columnlynx/common/utils.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace ColumnLynx::Net::TCP {
|
||||
void MessageHandler::start() {
|
||||
@@ -18,17 +17,17 @@ namespace ColumnLynx::Net::TCP {
|
||||
return static_cast<uint8_t>(type);
|
||||
}, type);
|
||||
|
||||
auto data = std::make_shared<std::vector<uint8_t>>();
|
||||
data->push_back(typeByte);
|
||||
std::vector<uint8_t> data;
|
||||
data.push_back(typeByte);
|
||||
uint16_t length = payload.size();
|
||||
|
||||
data->push_back(length >> 8);
|
||||
data->push_back(length & 0xFF);
|
||||
data.push_back(length >> 8);
|
||||
data.push_back(length & 0xFF);
|
||||
|
||||
data->insert(data->end(), payload.begin(), payload.end());
|
||||
data.insert(data.end(), payload.begin(), payload.end());
|
||||
auto self = shared_from_this();
|
||||
asio::async_write(mSocket, asio::buffer(*data),
|
||||
[self, data](asio::error_code ec, std::size_t) {
|
||||
asio::async_write(mSocket, asio::buffer(data),
|
||||
[self](asio::error_code ec, std::size_t) {
|
||||
if (ec) {
|
||||
Utils::error("Send failed: " + ec.message());
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace ColumnLynx::Utils {
|
||||
}
|
||||
|
||||
std::string getVersion() {
|
||||
return "1.1.1";
|
||||
return "1.1.0";
|
||||
}
|
||||
|
||||
unsigned short serverPort() {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <columnlynx/common/utils.hpp>
|
||||
#include <columnlynx/common/panic_handler.hpp>
|
||||
#include <columnlynx/server/net/tcp/tcp_server.hpp>
|
||||
@@ -173,24 +172,9 @@ int main(int argc, char** argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (packet.size() < 20) {
|
||||
Utils::warn("TUN: Dropping packet smaller than IPv4 header (" + std::to_string(packet.size()) + " bytes)");
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint8_t* ip = packet.data();
|
||||
uint8_t ipVersion = (ip[0] >> 4);
|
||||
if (ipVersion != 4) {
|
||||
Utils::debug("TUN: Non-IPv4 packet received (version=" + std::to_string(ipVersion) + "), skipping server IPv4 routing path.");
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t srcIPNet = 0;
|
||||
uint32_t dstIPNet = 0;
|
||||
std::memcpy(&srcIPNet, ip + 12, sizeof(srcIPNet)); // IPv4 source address offset
|
||||
std::memcpy(&dstIPNet, ip + 16, sizeof(dstIPNet)); // IPv4 destination address offset
|
||||
uint32_t srcIP = ntohl(srcIPNet);
|
||||
uint32_t dstIP = ntohl(dstIPNet);
|
||||
uint32_t srcIP = ntohl(*(uint32_t*)(ip + 12)); // IPv4 source address offset
|
||||
uint32_t dstIP = ntohl(*(uint32_t*)(ip + 16)); // IPv4 destination address offset
|
||||
|
||||
// First, check if destination IP is a registered client (e.g., server responding to client or client-to-client)
|
||||
auto dstSession = SessionRegistry::getInstance().getByIP(dstIP);
|
||||
|
||||
@@ -14,31 +14,23 @@ namespace ColumnLynx::Net::TCP {
|
||||
Utils::warn("Failed to get remote endpoint: " + std::string(e.what()));
|
||||
}
|
||||
|
||||
mHandler->onMessage([weakSelf = weak_from_this()](AnyMessageType type, const std::string& data) {
|
||||
if (auto self = weakSelf.lock()) {
|
||||
self->mHandleMessage(static_cast<ClientMessageType>(MessageHandler::toUint8(type)), data);
|
||||
}
|
||||
mHandler->onMessage([this](AnyMessageType type, const std::string& data) {
|
||||
mHandleMessage(static_cast<ClientMessageType>(MessageHandler::toUint8(type)), data);
|
||||
});
|
||||
|
||||
mHandler->onDisconnect([weakSelf = weak_from_this()](const asio::error_code& ec) {
|
||||
auto self = weakSelf.lock();
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
mHandler->onDisconnect([this](const asio::error_code& ec) {
|
||||
// Peer has closed; finalize locally without sending RST
|
||||
Utils::log("Client disconnected: " + self->mRemoteIP + " - " + ec.message());
|
||||
Utils::log("Client disconnected: " + mRemoteIP + " - " + ec.message());
|
||||
asio::error_code ec2;
|
||||
if (self->mHandler) {
|
||||
self->mHandler->socket().close(ec2);
|
||||
}
|
||||
mHandler->socket().close(ec2);
|
||||
|
||||
SessionRegistry::getInstance().erase(self->mConnectionSessionID);
|
||||
SessionRegistry::getInstance().deallocIP(self->mConnectionSessionID);
|
||||
SessionRegistry::getInstance().erase(mConnectionSessionID);
|
||||
SessionRegistry::getInstance().deallocIP(mConnectionSessionID);
|
||||
|
||||
Utils::log("Closed connection to " + self->mRemoteIP);
|
||||
Utils::log("Closed connection to " + mRemoteIP);
|
||||
|
||||
if (self->mOnDisconnect) {
|
||||
self->mOnDisconnect(self);
|
||||
if (mOnDisconnect) {
|
||||
mOnDisconnect(shared_from_this());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -85,7 +77,7 @@ namespace ColumnLynx::Net::TCP {
|
||||
void TCPConnection::mStartHeartbeat() {
|
||||
auto self = shared_from_this();
|
||||
mHeartbeatTimer.expires_after(std::chrono::seconds(5));
|
||||
mHeartbeatTimer.async_wait([self](const asio::error_code& ec) {
|
||||
mHeartbeatTimer.async_wait([this, self](const asio::error_code& ec) {
|
||||
if (ec == asio::error::operation_aborted) {
|
||||
return; // Timer was cancelled
|
||||
}
|
||||
@@ -98,13 +90,10 @@ namespace ColumnLynx::Net::TCP {
|
||||
|
||||
// Remove socket forcefully, client is dead
|
||||
asio::error_code ec;
|
||||
if (self->mHandler) {
|
||||
self->mHandler->socket().shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||
self->mHandler->socket().close(ec);
|
||||
}
|
||||
mHandler->socket().shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||
mHandler->socket().close(ec);
|
||||
|
||||
SessionRegistry::getInstance().erase(self->mConnectionSessionID);
|
||||
SessionRegistry::getInstance().deallocIP(self->mConnectionSessionID);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user