TESTING: Move server stuff to a server session config for central/global resources

This commit is contained in:
2026-02-09 14:20:26 +01:00
parent 6d40dbe00d
commit 316498c745
9 changed files with 213 additions and 56 deletions

View File

@@ -18,6 +18,7 @@
#include <columnlynx/common/net/session_registry.hpp>
#include <columnlynx/common/net/protocol_structs.hpp>
#include <columnlynx/common/net/virtual_interface.hpp>
#include <columnlynx/server/server_session.hpp>
namespace ColumnLynx::Net::TCP {
class TCPConnection : public std::enable_shared_from_this<TCPConnection> {
@@ -26,12 +27,9 @@ namespace ColumnLynx::Net::TCP {
static pointer create(
asio::ip::tcp::socket socket,
std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper,
std::unordered_map<std::string, std::string>* serverConfig,
std::string configDirPath,
std::function<void(pointer)> onDisconnect)
{
auto conn = pointer(new TCPConnection(std::move(socket), sodiumWrapper, serverConfig, configDirPath));
auto conn = pointer(new TCPConnection(std::move(socket)));
conn->mOnDisconnect = std::move(onDisconnect);
return conn;
}
@@ -51,15 +49,12 @@ namespace ColumnLynx::Net::TCP {
std::array<uint8_t, 32> getAESKey() const;
private:
TCPConnection(asio::ip::tcp::socket socket, std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper, std::unordered_map<std::string, std::string>* serverConfig, std::string configDirPath)
TCPConnection(asio::ip::tcp::socket socket)
:
mHandler(std::make_shared<MessageHandler>(std::move(socket))),
mLibSodiumWrapper(sodiumWrapper),
mRawServerConfig(serverConfig),
mHeartbeatTimer(mHandler->socket().get_executor()),
mLastHeartbeatReceived(std::chrono::steady_clock::now()),
mLastHeartbeatSent(std::chrono::steady_clock::now()),
mConfigDirPath(configDirPath)
mLastHeartbeatSent(std::chrono::steady_clock::now())
{}
// Start the heartbeat routine
@@ -69,8 +64,6 @@ namespace ColumnLynx::Net::TCP {
std::shared_ptr<MessageHandler> mHandler;
std::function<void(std::shared_ptr<TCPConnection>)> mOnDisconnect;
std::shared_ptr<Utils::LibSodiumWrapper> mLibSodiumWrapper;
std::unordered_map<std::string, std::string>* mRawServerConfig;
std::array<uint8_t, 32> mConnectionAESKey;
uint64_t mConnectionSessionID;
AsymPublicKey mConnectionPublicKey;
@@ -79,6 +72,5 @@ namespace ColumnLynx::Net::TCP {
std::chrono::steady_clock::time_point mLastHeartbeatSent;
int mMissedHeartbeats = 0;
std::string mRemoteIP; // Cached remote IP to avoid calling remote_endpoint() on closed sockets
std::string mConfigDirPath;
};
}

View File

@@ -17,29 +17,23 @@
#include <columnlynx/server/net/tcp/tcp_connection.hpp>
#include <columnlynx/common/libsodium_wrapper.hpp>
#include <columnlynx/common/net/protocol_structs.hpp>
#include <columnlynx/server/server_session.hpp>
namespace ColumnLynx::Net::TCP {
class TCPServer {
public:
TCPServer(asio::io_context& ioContext,
uint16_t port,
std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper,
std::shared_ptr<bool> hostRunning,
std::string& configPath,
bool ipv4Only = false)
uint16_t port)
: mIoContext(ioContext),
mAcceptor(ioContext),
mSodiumWrapper(sodiumWrapper),
mHostRunning(hostRunning),
mConfigDirPath(configPath)
mAcceptor(ioContext)
{
// Preload the config map
mRawServerConfig = Utils::getConfigMap(configPath + "server_config", {"NETWORK", "SUBNET_MASK"});
asio::error_code ec_open, ec_v6only, ec_bind;
if (!ipv4Only) {
bool isIPv4Only = ServerSession::getInstance().isIPv4Only();
if (!isIPv4Only) {
// Try IPv6 (dual-stack if supported)
asio::ip::tcp::endpoint endpoint_v6(asio::ip::tcp::v6(), port);
@@ -55,8 +49,8 @@ namespace ColumnLynx::Net::TCP {
}
// If IPv6 bind failed OR IPv6 open failed OR forced IPv4-only
if (ipv4Only || ec_open || ec_bind) {
if (!ipv4Only)
if (isIPv4Only || ec_open || ec_bind) {
if (!isIPv4Only)
Utils::warn("TCP: IPv6 unavailable (open=" + ec_open.message() +
", bind=" + ec_bind.message() +
"), falling back to IPv4 only");
@@ -84,10 +78,6 @@ namespace ColumnLynx::Net::TCP {
asio::io_context &mIoContext;
asio::ip::tcp::acceptor mAcceptor;
std::unordered_set<TCPConnection::pointer> mClients;
std::shared_ptr<Utils::LibSodiumWrapper> mSodiumWrapper;
std::shared_ptr<bool> mHostRunning;
std::unordered_map<std::string, std::string> mRawServerConfig;
std::string mConfigDirPath;
};
}

View File

@@ -9,16 +9,18 @@
#include <columnlynx/common/utils.hpp>
#include <array>
#include <columnlynx/common/net/virtual_interface.hpp>
#include <columnlynx/common/libsodium_wrapper.hpp>
#include <columnlynx/server/server_session.hpp>
namespace ColumnLynx::Net::UDP {
class UDPServer {
public:
UDPServer(asio::io_context& ioContext, uint16_t port, std::shared_ptr<bool> hostRunning, bool ipv4Only = false, std::shared_ptr<VirtualInterface> tun = nullptr)
: mSocket(ioContext), mHostRunning(hostRunning), mTun(tun)
UDPServer(asio::io_context& ioContext, uint16_t port)
: mSocket(ioContext)
{
asio::error_code ec_open, ec_v6only, ec_bind;
if (!ipv4Only) {
if (!mIpv4Only) {
asio::ip::udp::endpoint endpoint_v6(asio::ip::udp::v6(), port);
// Try opening IPv6 socket
@@ -34,8 +36,8 @@ namespace ColumnLynx::Net::UDP {
}
// Fallback to IPv4 if IPv6 is unusable
if (ipv4Only || ec_open || ec_bind) {
if (!ipv4Only) {
if (mIpv4Only || ec_open || ec_bind) {
if (!mIpv4Only) {
Utils::warn(
"UDP: IPv6 unavailable (open=" + ec_open.message() +
", bind=" + ec_bind.message() +
@@ -70,7 +72,7 @@ namespace ColumnLynx::Net::UDP {
asio::ip::udp::socket mSocket;
asio::ip::udp::endpoint mRemoteEndpoint;
std::array<uint8_t, 2048> mRecvBuffer; // 2048 seems stable
std::shared_ptr<bool> mHostRunning;
std::shared_ptr<VirtualInterface> mTun;
bool mIpv4Only = ServerSession::getInstance().isIPv4Only();
const std::shared_ptr<VirtualInterface> mTun = ServerSession::getInstance().getVirtualInterface();
};
}

View File

@@ -0,0 +1,62 @@
// server_session.hpp - Client Session data for ColumnLynx
// Copyright (C) 2026 DcruBro
// Distributed under the terms of the GNU General Public License, either version 2 only or version 3. See LICENSES/ for details.
#pragma once
#include <memory>
#include <columnlynx/common/libsodium_wrapper.hpp>
#include <array>
#include <columnlynx/common/net/virtual_interface.hpp>
#include <shared_mutex>
namespace ColumnLynx {
struct ServerState {
std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper;
std::shared_ptr<Net::VirtualInterface> virtualInterface;
std::string configPath;
std::unordered_map<std::string, std::string> serverConfig;
bool ipv4Only;
bool hostRunning;
~ServerState() = default;
ServerState(const ServerState&) = delete;
ServerState& operator=(const ServerState&) = delete;
ServerState(ServerState&&) = default;
ServerState& operator=(ServerState&&) = default;
explicit ServerState() = default;
};
class ServerSession {
public:
// Return a reference to the Server Session instance
static ServerSession& getInstance() { static ServerSession instance; return instance; }
// Return the current server state
std::shared_ptr<ServerState> getServerState() const;
// Set the server state
void setServerState(std::shared_ptr<ServerState> state);
// Getters
std::shared_ptr<Utils::LibSodiumWrapper> getSodiumWrapper() const;
const std::string& getConfigPath() const;
const std::unordered_map<std::string, std::string>& getRawServerConfig() const;
const std::shared_ptr<Net::VirtualInterface>& getVirtualInterface() const;
bool isIPv4Only() const;
bool isHostRunning() const;
// Setters
void setSodiumWrapper(std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper);
void setConfigPath(const std::string& configPath);
void setRawServerConfig(const std::unordered_map<std::string, std::string>& config);
void setVirtualInterface(std::shared_ptr<Net::VirtualInterface> tun);
void setIPv4Only(bool ipv4Only);
void setHostRunning(bool hostRunning);
private:
mutable std::shared_mutex mMutex;
std::shared_ptr<struct ServerState> mServerState{nullptr};
};
}