TESTING: Move server stuff to a server session config for central/global resources
This commit is contained in:
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
62
include/columnlynx/server/server_session.hpp
Normal file
62
include/columnlynx/server/server_session.hpp
Normal 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};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user