minor fixes relating to nonce overflows, size checks, etc.

This commit is contained in:
2026-05-25 12:22:33 +02:00
parent b64d9c4498
commit 60795c60d8
5 changed files with 38 additions and 6 deletions

View File

@@ -87,6 +87,10 @@ namespace ColumnLynx {
void incrementSendCount() {
std::unique_lock lock(mMutex);
if (mClientState->send_cnt == std::numeric_limits<uint64_t>::max()) {
Utils::error("ClientSession: send counter overflow detected");
return;
}
mClientState->send_cnt++;
}

View File

@@ -3,6 +3,8 @@
// Distributed under the terms of the GNU General Public License, either version 2 only or version 3. See LICENSES/ for details.
#include <columnlynx/client/net/udp/udp_client.hpp>
#include <thread>
#include <chrono>
namespace ColumnLynx::Net::UDP {
void UDPClient::start() {
@@ -102,7 +104,12 @@ namespace ColumnLynx::Net::UDP {
if (ec) {
if (ec == asio::error::operation_aborted) return; // Socket closed
// Other recv error
mStartReceive();
Utils::warn("UDPClient receive error: " + ec.message());
// Back off briefly before restarting receive to avoid busy error loops
asio::post(mSocket.get_executor(), [this]() {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
mStartReceive();
});
return;
}

View File

@@ -213,8 +213,8 @@ static bool runCommand(const std::vector<std::string>& args) {
pfd.fd = mFd;
pfd.events = POLLIN;
// timeout in ms; keep it small so shutdown is responsive
int ret = poll(&pfd, 1, 200);
// timeout in ms; keep it small so shutdown is responsive. Reduced for lower latency.
int ret = poll(&pfd, 1, 50);
if (ret == 0) {
// No data yet

View File

@@ -213,8 +213,13 @@ int main(int argc, char** argv) {
// 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);
if (dstSession) {
// Destination is a registered client, forward to that client's session
udpServer->sendData(dstSession->sessionID, std::string(packet.begin(), packet.end()));
// Destination is a registered client, enforce MTU and forward to that client's session
const size_t MTU = 1420; // Enforce configured MTU; TODO: read from server config
if (packet.size() > MTU) {
Utils::warn("TUN: Dropping oversized packet (" + std::to_string(packet.size()) + " > MTU " + std::to_string(MTU) + ")");
} else {
udpServer->sendData(dstSession->sessionID, std::string(packet.begin(), packet.end()));
}
continue;
}

View File

@@ -95,7 +95,23 @@ namespace ColumnLynx::Net::UDP {
UDPPacketHeader hdr{};
uint8_t nonce[12];
uint32_t prefix = session->noncePrefix;
uint64_t sendCount = const_cast<SessionState*>(session.get())->send_ctr.fetch_add(1, std::memory_order_relaxed);
// Increment send counter with overflow protection
uint64_t sendCount = 0;
{
auto ptr = const_cast<SessionState*>(session.get());
uint64_t old = ptr->send_ctr.load(std::memory_order_relaxed);
for (;;) {
if (old == std::numeric_limits<uint64_t>::max()) {
Utils::error("UDP: send counter overflow for session " + std::to_string(sessionID));
return;
}
if (ptr->send_ctr.compare_exchange_weak(old, old + 1, std::memory_order_relaxed)) {
sendCount = old;
break;
}
// old updated by compare_exchange_weak, loop
}
}
memcpy(nonce, &prefix, sizeof(uint32_t)); // Prefix nonce
memcpy(nonce + sizeof(uint32_t), &sendCount, sizeof(uint64_t)); // Use send count as nonce suffix to ensure uniqueness
std::copy_n(nonce, 12, hdr.nonce.data());