TESTING: protocol version 2
This commit is contained in:
@@ -17,7 +17,10 @@ namespace ColumnLynx {
|
||||
bool insecureMode;
|
||||
std::string configPath;
|
||||
std::shared_ptr<Net::VirtualInterface> virtualInterface;
|
||||
uint64_t sessionID;
|
||||
uint32_t sessionID;
|
||||
uint64_t recv_cnt;
|
||||
uint64_t send_cnt;
|
||||
uint32_t noncePrefix;
|
||||
|
||||
~ClientState() { sodium_memzero(aesKey.data(), aesKey.size()); }
|
||||
ClientState(const ClientState&) = delete;
|
||||
@@ -28,8 +31,8 @@ namespace ColumnLynx {
|
||||
explicit ClientState() = default;
|
||||
|
||||
explicit ClientState(std::shared_ptr<Utils::LibSodiumWrapper> sodium, SymmetricKey& k, bool insecure,
|
||||
std::string& config, std::shared_ptr<Net::VirtualInterface> tun, uint64_t session)
|
||||
: sodiumWrapper(sodium), aesKey(k), insecureMode(insecure), configPath(config), virtualInterface(tun), sessionID(session) {}
|
||||
std::string& config, std::shared_ptr<Net::VirtualInterface> tun, uint32_t session, uint64_t recv, uint64_t send)
|
||||
: sodiumWrapper(sodium), aesKey(k), insecureMode(insecure), configPath(config), virtualInterface(tun), sessionID(session), recv_cnt(recv), send_cnt(send) {}
|
||||
};
|
||||
|
||||
class ClientSession {
|
||||
@@ -54,7 +57,21 @@ namespace ColumnLynx {
|
||||
// Get the virtual interface
|
||||
const std::shared_ptr<Net::VirtualInterface>& getVirtualInterface() const;
|
||||
// Get the session ID
|
||||
uint64_t getSessionID() const;
|
||||
uint32_t getSessionID() const;
|
||||
uint64_t getRecvCount() const {
|
||||
std::shared_lock lock(mMutex);
|
||||
return mClientState->recv_cnt;
|
||||
}
|
||||
|
||||
uint64_t getSendCount() const {
|
||||
std::shared_lock lock(mMutex);
|
||||
return mClientState->send_cnt;
|
||||
}
|
||||
|
||||
uint32_t getNoncePrefix() const {
|
||||
std::shared_lock lock(mMutex);
|
||||
return mClientState->noncePrefix;
|
||||
}
|
||||
|
||||
// Setters
|
||||
void setSodiumWrapper(std::shared_ptr<Utils::LibSodiumWrapper> sodiumWrapper);
|
||||
@@ -62,7 +79,21 @@ namespace ColumnLynx {
|
||||
void setInsecureMode(bool insecureMode);
|
||||
void setConfigPath(const std::string& configPath);
|
||||
void setVirtualInterface(std::shared_ptr<Net::VirtualInterface> virtualInterface);
|
||||
void setSessionID(uint64_t sessionID);
|
||||
void setSessionID(uint32_t sessionID);
|
||||
void incrementRecvCount() {
|
||||
std::unique_lock lock(mMutex);
|
||||
mClientState->recv_cnt++;
|
||||
}
|
||||
|
||||
void incrementSendCount() {
|
||||
std::unique_lock lock(mMutex);
|
||||
mClientState->send_cnt++;
|
||||
}
|
||||
|
||||
void setNoncePrefix(uint32_t prefix) {
|
||||
std::unique_lock lock(mMutex);
|
||||
mClientState->noncePrefix = prefix;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::shared_mutex mMutex;
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace ColumnLynx::Net::TCP {
|
||||
std::string mHost, mPort;
|
||||
uint8_t mServerPublicKey[32]; // Assuming 256-bit public key
|
||||
std::array<uint8_t, 32> mSubmittedChallenge{};
|
||||
uint64_t mConnectionSessionID;
|
||||
uint32_t mConnectionSessionID;
|
||||
SymmetricKey mConnectionAESKey;
|
||||
asio::steady_timer mHeartbeatTimer;
|
||||
std::chrono::steady_clock::time_point mLastHeartbeatReceived;
|
||||
|
||||
@@ -27,8 +27,9 @@ namespace ColumnLynx::Net {
|
||||
std::chrono::steady_clock::time_point expires{}; // Time of expiry
|
||||
uint32_t clientTunIP; // Assigned IP
|
||||
uint32_t serverTunIP; // Server IP
|
||||
uint64_t sessionID; // Session ID
|
||||
uint32_t sessionID; // Session ID
|
||||
Nonce base_nonce{};
|
||||
uint32_t noncePrefix;
|
||||
|
||||
~SessionState() { sodium_memzero(aesKey.data(), aesKey.size()); }
|
||||
SessionState(const SessionState&) = delete;
|
||||
@@ -36,7 +37,7 @@ namespace ColumnLynx::Net {
|
||||
SessionState(SessionState&&) = default;
|
||||
SessionState& operator=(SessionState&&) = default;
|
||||
|
||||
explicit SessionState(const SymmetricKey& k, std::chrono::seconds ttl = std::chrono::hours(24), uint32_t clientIP = 0, uint32_t serverIP = 0, uint64_t id = 0) : aesKey(k), clientTunIP(clientIP), serverTunIP(serverIP), sessionID(id) {
|
||||
explicit SessionState(const SymmetricKey& k, std::chrono::seconds ttl = std::chrono::hours(24), uint32_t clientIP = 0, uint32_t serverIP = 0, uint32_t id = 0) : aesKey(k), clientTunIP(clientIP), serverTunIP(serverIP), sessionID(id) {
|
||||
expires = created + ttl;
|
||||
}
|
||||
|
||||
@@ -44,6 +45,11 @@ namespace ColumnLynx::Net {
|
||||
void setUDPEndpoint(const asio::ip::udp::endpoint& ep) {
|
||||
udpEndpoint = ep;
|
||||
}
|
||||
|
||||
void setBaseNonce() {
|
||||
Utils::debug("Generating random base nonce for session " + std::to_string(sessionID));
|
||||
randombytes_buf(base_nonce.data(), base_nonce.size());
|
||||
}
|
||||
};
|
||||
|
||||
class SessionRegistry {
|
||||
@@ -52,19 +58,19 @@ namespace ColumnLynx::Net {
|
||||
static SessionRegistry& getInstance() { static SessionRegistry instance; return instance; }
|
||||
|
||||
// Insert or replace a session entry
|
||||
void put(uint64_t sessionID, std::shared_ptr<SessionState> state);
|
||||
void put(uint32_t sessionID, std::shared_ptr<SessionState> state);
|
||||
|
||||
// Lookup a session entry by session ID
|
||||
std::shared_ptr<const SessionState> get(uint64_t sessionID) const;
|
||||
std::shared_ptr<const SessionState> get(uint32_t sessionID) const;
|
||||
|
||||
// Lookup a session entry by IPv4
|
||||
std::shared_ptr<const SessionState> getByIP(uint32_t ip) const;
|
||||
|
||||
// Get a snapshot of the Session Registry
|
||||
std::unordered_map<uint64_t, std::shared_ptr<SessionState>> snapshot() const;
|
||||
std::unordered_map<uint32_t, std::shared_ptr<SessionState>> snapshot() const;
|
||||
|
||||
// Remove a session by ID
|
||||
void erase(uint64_t sessionID);
|
||||
void erase(uint32_t sessionID);
|
||||
|
||||
// Cleanup expired sessions
|
||||
void cleanupExpired();
|
||||
@@ -78,15 +84,15 @@ namespace ColumnLynx::Net {
|
||||
uint32_t getFirstAvailableIP(uint32_t baseIP, uint8_t mask) const;
|
||||
|
||||
// Lock IP to session ID; Do NOT call before put() - You will segfault!
|
||||
void lockIP(uint64_t sessionID, uint32_t ip);
|
||||
void lockIP(uint32_t sessionID, uint32_t ip);
|
||||
|
||||
// Unlock IP from session ID
|
||||
void deallocIP(uint64_t sessionID);
|
||||
void deallocIP(uint32_t sessionID);
|
||||
|
||||
private:
|
||||
mutable std::shared_mutex mMutex;
|
||||
std::unordered_map<uint64_t, std::shared_ptr<SessionState>> mSessions;
|
||||
std::unordered_map<uint64_t, uint32_t> mSessionIPs;
|
||||
std::unordered_map<uint32_t, std::shared_ptr<SessionState>> mSessions;
|
||||
std::unordered_map<uint32_t, uint32_t> mSessionIPs;
|
||||
std::unordered_map<uint32_t, std::shared_ptr<SessionState>> mIPSessions;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -65,27 +65,6 @@ namespace ColumnLynx::Utils {
|
||||
return std::string(reinterpret_cast<const char*>(data), length);
|
||||
}
|
||||
|
||||
inline constexpr uint64_t cbswap64(uint64_t x) {
|
||||
return ((x & 0x00000000000000FFULL) << 56) |
|
||||
((x & 0x000000000000FF00ULL) << 40) |
|
||||
((x & 0x0000000000FF0000ULL) << 24) |
|
||||
((x & 0x00000000FF000000ULL) << 8) |
|
||||
((x & 0x000000FF00000000ULL) >> 8) |
|
||||
((x & 0x0000FF0000000000ULL) >> 24) |
|
||||
((x & 0x00FF000000000000ULL) >> 40) |
|
||||
((x & 0xFF00000000000000ULL) >> 56);
|
||||
}
|
||||
|
||||
// host -> big-endian (for little-endian hosts) - 64 bit
|
||||
inline constexpr uint64_t chtobe64(uint64_t x) {
|
||||
return cbswap64(x);
|
||||
}
|
||||
|
||||
// big-endian -> host (for little-endian hosts) - 64 bit
|
||||
inline constexpr uint64_t cbe64toh(uint64_t x) {
|
||||
return cbswap64(x);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T cbswap128(const T& x) {
|
||||
static_assert(sizeof(T) == 16, "cbswap128 requires a 128-bit type");
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace ColumnLynx::Net::TCP {
|
||||
void disconnect(bool echo = true);
|
||||
|
||||
// Get the assigned session ID
|
||||
uint64_t getSessionID() const;
|
||||
uint32_t getSessionID() const;
|
||||
// Get the assigned AES key; You should probably access this via the Session Registry instead
|
||||
std::array<uint8_t, 32> getAESKey() const;
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace ColumnLynx::Net::TCP {
|
||||
std::shared_ptr<MessageHandler> mHandler;
|
||||
std::function<void(std::shared_ptr<TCPConnection>)> mOnDisconnect;
|
||||
std::array<uint8_t, 32> mConnectionAESKey;
|
||||
uint64_t mConnectionSessionID;
|
||||
uint32_t mConnectionSessionID;
|
||||
AsymPublicKey mConnectionPublicKey;
|
||||
asio::steady_timer mHeartbeatTimer;
|
||||
std::chrono::steady_clock::time_point mLastHeartbeatReceived;
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace ColumnLynx::Net::UDP {
|
||||
void stop();
|
||||
|
||||
// Send UDP data to an endpoint; Fetched via the Session Registry
|
||||
void sendData(const uint64_t sessionID, const std::string& data);
|
||||
void sendData(uint32_t sessionID, const std::string& data);
|
||||
|
||||
private:
|
||||
// Start receiving UDP data
|
||||
|
||||
Reference in New Issue
Block a user