minor fixes relating to nonce overflows, size checks, etc.
This commit is contained in:
@@ -87,6 +87,10 @@ namespace ColumnLynx {
|
|||||||
|
|
||||||
void incrementSendCount() {
|
void incrementSendCount() {
|
||||||
std::unique_lock lock(mMutex);
|
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++;
|
mClientState->send_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
// 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 <columnlynx/client/net/udp/udp_client.hpp>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
namespace ColumnLynx::Net::UDP {
|
namespace ColumnLynx::Net::UDP {
|
||||||
void UDPClient::start() {
|
void UDPClient::start() {
|
||||||
@@ -102,7 +104,12 @@ namespace ColumnLynx::Net::UDP {
|
|||||||
if (ec) {
|
if (ec) {
|
||||||
if (ec == asio::error::operation_aborted) return; // Socket closed
|
if (ec == asio::error::operation_aborted) return; // Socket closed
|
||||||
// Other recv error
|
// Other recv error
|
||||||
|
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();
|
mStartReceive();
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,8 +213,8 @@ static bool runCommand(const std::vector<std::string>& args) {
|
|||||||
pfd.fd = mFd;
|
pfd.fd = mFd;
|
||||||
pfd.events = POLLIN;
|
pfd.events = POLLIN;
|
||||||
|
|
||||||
// timeout in ms; keep it small so shutdown is responsive
|
// timeout in ms; keep it small so shutdown is responsive. Reduced for lower latency.
|
||||||
int ret = poll(&pfd, 1, 200);
|
int ret = poll(&pfd, 1, 50);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
// No data yet
|
// No data yet
|
||||||
|
|||||||
@@ -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)
|
// 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);
|
auto dstSession = SessionRegistry::getInstance().getByIP(dstIP);
|
||||||
if (dstSession) {
|
if (dstSession) {
|
||||||
// Destination is a registered client, forward to that client's session
|
// 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()));
|
udpServer->sendData(dstSession->sessionID, std::string(packet.begin(), packet.end()));
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,23 @@ namespace ColumnLynx::Net::UDP {
|
|||||||
UDPPacketHeader hdr{};
|
UDPPacketHeader hdr{};
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
uint32_t prefix = session->noncePrefix;
|
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, &prefix, sizeof(uint32_t)); // Prefix nonce
|
||||||
memcpy(nonce + sizeof(uint32_t), &sendCount, sizeof(uint64_t)); // Use send count as nonce suffix to ensure uniqueness
|
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());
|
std::copy_n(nonce, 12, hdr.nonce.data());
|
||||||
|
|||||||
Reference in New Issue
Block a user