Added protocol version to TCP header, also some launch args

This commit is contained in:
2025-11-09 02:26:44 +01:00
parent 098afeb4d8
commit 2cbcf70c56
11 changed files with 3124 additions and 10 deletions

View File

@@ -45,7 +45,16 @@ namespace ColumnLynx::Net::TCP {
// Init connection handshake
Utils::log("Sending handshake init to server.");
mHandler->sendMessage(ClientMessageType::HANDSHAKE_INIT, Utils::uint8ArrayToString(mLibSodiumWrapper->getXPublicKey(), crypto_box_PUBLICKEYBYTES));
std::vector<uint8_t> payload;
payload.reserve(1 + crypto_box_PUBLICKEYBYTES);
payload.push_back(Utils::protocolVersion());
payload.insert(payload.end(),
mLibSodiumWrapper->getXPublicKey(),
mLibSodiumWrapper->getXPublicKey() + crypto_box_PUBLICKEYBYTES
);
mHandler->sendMessage(ClientMessageType::HANDSHAKE_INIT, Utils::uint8ArrayToString(payload.data(), payload.size()));
} else {
Utils::error("Client connect failed: " + ec.message());
}

View File

@@ -18,7 +18,7 @@ namespace ColumnLynx::Net::UDP {
const std::string& port,
std::array<uint8_t, 32>* aesKeyRef,
uint64_t* sessionIDRef)
: mSocket(ioContext), mResolver(ioContext), mHost(host), mPort(port), mAesKeyRef(aesKeyRef), mSessionIDRef(sessionIDRef) {}
: mSocket(ioContext), mResolver(ioContext), mHost(host), mPort(port), mAesKeyRef(aesKeyRef), mSessionIDRef(sessionIDRef) { mStartReceive(); }
void start() {
auto endpoints = mResolver.resolve(asio::ip::udp::v4(), mHost, mPort);
@@ -58,7 +58,73 @@ namespace ColumnLynx::Net::UDP {
Utils::log("Sent UDP packet of size " + std::to_string(packet.size()));
}
void stop() {
if (mSocket.is_open()) {
asio::error_code ec;
mSocket.cancel(ec);
mSocket.close(ec);
Utils::log("UDP Client socket closed.");
}
}
private:
void mStartReceive() {
mSocket.async_receive_from(
asio::buffer(mRecvBuffer), mRemoteEndpoint,
[this](asio::error_code ec, std::size_t bytes) {
if (ec) {
if (ec == asio::error::operation_aborted) return; // Socket closed
// Other recv error
mStartReceive();
return;
}
if (bytes > 0) {
mHandlePacket(bytes);
}
mStartReceive();
}
);
}
void mHandlePacket(std::size_t bytes) {
if (bytes < sizeof(UDPPacketHeader) + sizeof(uint64_t)) {
Utils::warn("UDP Client received packet too small to process.");
return;
}
// Parse header
UDPPacketHeader hdr;
std::memcpy(&hdr, mRecvBuffer.data(), sizeof(UDPPacketHeader));
// Parse session ID
uint64_t sessionID;
std::memcpy(&sessionID, mRecvBuffer.data() + sizeof(UDPPacketHeader), sizeof(uint64_t));
// Decrypt payload
std::vector<uint8_t> ciphertext(
mRecvBuffer.begin() + sizeof(UDPPacketHeader) + sizeof(uint64_t),
mRecvBuffer.begin() + bytes
);
if (mAesKeyRef == nullptr) {
Utils::error("UDP Client AES key reference is null!");
return;
}
std::vector<uint8_t> plaintext = Utils::LibSodiumWrapper::decryptMessage(
ciphertext.data(), ciphertext.size(), *mAesKeyRef, hdr.nonce, "udp-data"
);
if (plaintext.empty()) {
Utils::warn("UDP Client failed to decrypt received packet.");
return;
}
Utils::log("UDP Client received packet from " + mRemoteEndpoint.address().to_string() + " - Packet size: " + std::to_string(bytes));
}
asio::ip::udp::socket mSocket;
asio::ip::udp::resolver mResolver;
asio::ip::udp::endpoint mRemoteEndpoint;
@@ -66,5 +132,6 @@ namespace ColumnLynx::Net::UDP {
std::string mPort;
std::array<uint8_t, 32>* mAesKeyRef;
uint64_t* mSessionIDRef;
std::array<uint8_t, 2048> mRecvBuffer; // Adjust size as needed
};
}

View File

@@ -5,6 +5,8 @@
#pragma once
#include <iostream>
#include <string>
#include <cstdint>
#include <array>
#ifdef _WIN32
#include <winsock2.h>
@@ -22,6 +24,7 @@ namespace ColumnLynx::Utils {
std::string getHostname();
std::string getVersion();
unsigned short serverPort();
unsigned char protocolVersion();
// Raw byte to hex string conversion helper
std::string bytesToHexString(const uint8_t* bytes, size_t length);

View File

@@ -92,7 +92,24 @@ namespace ColumnLynx::Net::TCP {
switch (type) {
case ClientMessageType::HANDSHAKE_INIT: {
Utils::log("Received HANDSHAKE_INIT from " + reqAddr);
std::memcpy(mConnectionPublicKey.data(), data.data(), std::min(data.size(), sizeof(mConnectionPublicKey))); // Store the client's public key (for identification)
if (data.size() < 1 + crypto_box_PUBLICKEYBYTES) {
Utils::warn("HANDSHAKE_INIT from " + reqAddr + " is too short.");
disconnect();
return;
}
uint8_t clientProtoVer = static_cast<uint8_t>(data[0]);
if (clientProtoVer != Utils::protocolVersion()) {
Utils::warn("Client protocol version mismatch from " + reqAddr + ". Expected " +
std::to_string(Utils::protocolVersion()) + ", got " + std::to_string(clientProtoVer) + ".");
disconnect();
return;
}
Utils::log("Client protocol version " + std::to_string(clientProtoVer) + " accepted from " + reqAddr + ".");
std::memcpy(mConnectionPublicKey.data(), data.data() + 1, std::min(data.size() - 1, sizeof(mConnectionPublicKey))); // Store the client's public key (for identification)
mHandler->sendMessage(ServerMessageType::HANDSHAKE_IDENTIFY, Utils::uint8ArrayToString(mLibSodiumWrapper->getPublicKey(), crypto_sign_PUBLICKEYBYTES)); // This public key should always exist
break;
}