minor fixes relating to nonce overflows, size checks, etc.
This commit is contained in:
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user