Fixes and improvements (add use of TSLQueue)
Replace "unsigned long long" in TSLQueue with "unsigned long" to keep compatibility with C. Add top_and_pop_and_rsize() to TSLQueue. Fix log levels in UDPC. Replace TSQueue with TSLQueue in UDPC_Context. Also fix NetworkTest with TSLQueue related changes.
This commit is contained in:
parent
742db465dd
commit
7c889eee6a
5 changed files with 145 additions and 89 deletions
|
@ -30,10 +30,11 @@ class TSLQueue {
|
||||||
bool pop();
|
bool pop();
|
||||||
std::optional<T> top_and_pop();
|
std::optional<T> top_and_pop();
|
||||||
std::optional<T> top_and_pop_and_empty(bool *isEmpty);
|
std::optional<T> top_and_pop_and_empty(bool *isEmpty);
|
||||||
|
std::optional<T> top_and_pop_and_rsize(unsigned long *rsize);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
bool empty();
|
bool empty();
|
||||||
unsigned long long size();
|
unsigned long size();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TSLQNode {
|
struct TSLQNode {
|
||||||
|
@ -63,7 +64,7 @@ class TSLQueue {
|
||||||
public:
|
public:
|
||||||
TSLQIter(std::mutex &mutex,
|
TSLQIter(std::mutex &mutex,
|
||||||
std::weak_ptr<TSLQNode> currentNode,
|
std::weak_ptr<TSLQNode> currentNode,
|
||||||
unsigned long long *msize);
|
unsigned long *msize);
|
||||||
~TSLQIter();
|
~TSLQIter();
|
||||||
|
|
||||||
std::optional<T> current();
|
std::optional<T> current();
|
||||||
|
@ -74,7 +75,7 @@ class TSLQueue {
|
||||||
private:
|
private:
|
||||||
std::lock_guard<std::mutex> lock;
|
std::lock_guard<std::mutex> lock;
|
||||||
std::weak_ptr<TSLQNode> currentNode;
|
std::weak_ptr<TSLQNode> currentNode;
|
||||||
unsigned long long *const msize;
|
unsigned long *const msize;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ class TSLQueue {
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
std::shared_ptr<TSLQNode> head;
|
std::shared_ptr<TSLQNode> head;
|
||||||
std::shared_ptr<TSLQNode> tail;
|
std::shared_ptr<TSLQNode> tail;
|
||||||
unsigned long long msize;
|
unsigned long msize;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -243,6 +244,31 @@ std::optional<T> TSLQueue<T>::top_and_pop_and_empty(bool *isEmpty) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::optional<T> TSLQueue<T>::top_and_pop_and_rsize(unsigned long *rsize) {
|
||||||
|
std::optional<T> ret = std::nullopt;
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
|
if(head->next == tail) {
|
||||||
|
if(rsize) {
|
||||||
|
*rsize = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(head->next->data);
|
||||||
|
ret = *head->next->data.get();
|
||||||
|
|
||||||
|
auto& newNext = head->next->next;
|
||||||
|
newNext->prev = head;
|
||||||
|
head->next = newNext;
|
||||||
|
assert(msize > 0);
|
||||||
|
--msize;
|
||||||
|
|
||||||
|
if(rsize) {
|
||||||
|
*rsize = msize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TSLQueue<T>::clear() {
|
void TSLQueue<T>::clear() {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard lock(mutex);
|
||||||
|
@ -259,7 +285,7 @@ bool TSLQueue<T>::empty() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
unsigned long long TSLQueue<T>::size() {
|
unsigned long TSLQueue<T>::size() {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard lock(mutex);
|
||||||
return msize;
|
return msize;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +303,7 @@ bool TSLQueue<T>::TSLQNode::isNormal() const {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TSLQueue<T>::TSLQIter::TSLQIter(std::mutex &mutex,
|
TSLQueue<T>::TSLQIter::TSLQIter(std::mutex &mutex,
|
||||||
std::weak_ptr<TSLQNode> currentNode,
|
std::weak_ptr<TSLQNode> currentNode,
|
||||||
unsigned long long *msize) :
|
unsigned long *msize) :
|
||||||
lock(mutex),
|
lock(mutex),
|
||||||
currentNode(currentNode),
|
currentNode(currentNode),
|
||||||
msize(msize)
|
msize(msize)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "TSQueue.hpp"
|
#include "TSQueue.hpp"
|
||||||
|
#include "TSLQueue.hpp"
|
||||||
#include "UDPConnection.h"
|
#include "UDPConnection.h"
|
||||||
|
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
@ -153,6 +154,9 @@ private:
|
||||||
case UDPC_LoggingType::UDPC_INFO:
|
case UDPC_LoggingType::UDPC_INFO:
|
||||||
std::cerr << "INFO: ";
|
std::cerr << "INFO: ";
|
||||||
break;
|
break;
|
||||||
|
case UDPC_LoggingType::UDPC_DEBUG:
|
||||||
|
std::cerr << "DEBUG: ";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -197,8 +201,8 @@ public:
|
||||||
std::unordered_map<struct in6_addr, std::unordered_set<UDPC_ConnectionId, ConnectionIdHasher>, IPV6_Hasher> addrConMap;
|
std::unordered_map<struct in6_addr, std::unordered_set<UDPC_ConnectionId, ConnectionIdHasher>, IPV6_Hasher> addrConMap;
|
||||||
// id to ipv6 address and port (as UDPC_ConnectionId)
|
// id to ipv6 address and port (as UDPC_ConnectionId)
|
||||||
std::unordered_map<uint32_t, UDPC_ConnectionId> idMap;
|
std::unordered_map<uint32_t, UDPC_ConnectionId> idMap;
|
||||||
TSQueue<UDPC_PacketInfo> receivedPkts;
|
TSLQueue<UDPC_PacketInfo> receivedPkts;
|
||||||
TSQueue<UDPC_PacketInfo> cSendPkts;
|
TSLQueue<UDPC_PacketInfo> cSendPkts;
|
||||||
|
|
||||||
std::default_random_engine rng_engine;
|
std::default_random_engine rng_engine;
|
||||||
|
|
||||||
|
|
|
@ -165,13 +165,13 @@ flags(),
|
||||||
isAcceptNewConnections(true),
|
isAcceptNewConnections(true),
|
||||||
protocolID(UDPC_DEFAULT_PROTOCOL_ID),
|
protocolID(UDPC_DEFAULT_PROTOCOL_ID),
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
loggingType(UDPC_INFO),
|
loggingType(UDPC_DEBUG),
|
||||||
#else
|
#else
|
||||||
loggingType(UDPC_WARNING),
|
loggingType(UDPC_WARNING),
|
||||||
#endif
|
#endif
|
||||||
atostrBufIndex(0),
|
atostrBufIndex(0),
|
||||||
receivedPkts(UDPC_RECEIVED_PKTS_MAX_SIZE),
|
receivedPkts(),
|
||||||
cSendPkts(UDPC_QUEUED_PKTS_MAX_SIZE),
|
cSendPkts(),
|
||||||
rng_engine(),
|
rng_engine(),
|
||||||
mutex()
|
mutex()
|
||||||
{
|
{
|
||||||
|
@ -199,12 +199,21 @@ bool UDPC::Context::willLog(UDPC_LoggingType type) {
|
||||||
case UDPC_LoggingType::UDPC_WARNING:
|
case UDPC_LoggingType::UDPC_WARNING:
|
||||||
return type == UDPC_LoggingType::UDPC_ERROR
|
return type == UDPC_LoggingType::UDPC_ERROR
|
||||||
|| type == UDPC_LoggingType::UDPC_WARNING;
|
|| type == UDPC_LoggingType::UDPC_WARNING;
|
||||||
|
case UDPC_LoggingType::UDPC_INFO:
|
||||||
|
return type == UDPC_LoggingType::UDPC_ERROR
|
||||||
|
|| type == UDPC_LoggingType::UDPC_WARNING
|
||||||
|
|| type == UDPC_LoggingType::UDPC_INFO;
|
||||||
case UDPC_LoggingType::UDPC_VERBOSE:
|
case UDPC_LoggingType::UDPC_VERBOSE:
|
||||||
return type == UDPC_LoggingType::UDPC_ERROR
|
return type == UDPC_LoggingType::UDPC_ERROR
|
||||||
|| type == UDPC_LoggingType::UDPC_WARNING
|
|| type == UDPC_LoggingType::UDPC_WARNING
|
||||||
|
|| type == UDPC_LoggingType::UDPC_INFO
|
||||||
|| type == UDPC_LoggingType::UDPC_VERBOSE;
|
|| type == UDPC_LoggingType::UDPC_VERBOSE;
|
||||||
case UDPC_LoggingType::UDPC_INFO:
|
case UDPC_LoggingType::UDPC_DEBUG:
|
||||||
return type != UDPC_LoggingType::UDPC_SILENT;
|
return type == UDPC_LoggingType::UDPC_ERROR
|
||||||
|
|| type == UDPC_LoggingType::UDPC_WARNING
|
||||||
|
|| type == UDPC_LoggingType::UDPC_INFO
|
||||||
|
|| type == UDPC_LoggingType::UDPC_VERBOSE
|
||||||
|
|| type == UDPC_LoggingType::UDPC_DEBUG;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +247,7 @@ void UDPC::Context::update_impl() {
|
||||||
if(iter->second.flags.test(1) && !iter->second.flags.test(2)) {
|
if(iter->second.flags.test(1) && !iter->second.flags.test(2)) {
|
||||||
// good mode, bad rtt
|
// good mode, bad rtt
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Switching to bad mode in connection with ",
|
"Switching to bad mode in connection with ",
|
||||||
UDPC_atostr((UDPC_HContext)this, iter->first.addr),
|
UDPC_atostr((UDPC_HContext)this, iter->first.addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -264,7 +273,7 @@ void UDPC::Context::update_impl() {
|
||||||
iter->second.toggleTimer = std::chrono::steady_clock::duration::zero();
|
iter->second.toggleTimer = std::chrono::steady_clock::duration::zero();
|
||||||
iter->second.toggledTimer = std::chrono::steady_clock::duration::zero();
|
iter->second.toggledTimer = std::chrono::steady_clock::duration::zero();
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Switching to good mode in connection with ",
|
"Switching to good mode in connection with ",
|
||||||
UDPC_atostr((UDPC_HContext)this, iter->first.addr),
|
UDPC_atostr((UDPC_HContext)this, iter->first.addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -315,13 +324,33 @@ void UDPC::Context::update_impl() {
|
||||||
|
|
||||||
// move queued in cSendPkts to existing connection's sendPkts
|
// move queued in cSendPkts to existing connection's sendPkts
|
||||||
{
|
{
|
||||||
unsigned int rsize = 0;
|
auto sendIter = cSendPkts.begin();
|
||||||
do {
|
while(true) {
|
||||||
auto next = cSendPkts.top_and_pop_and_rsize(&rsize);
|
auto next = sendIter.current();
|
||||||
if(next) {
|
if(next) {
|
||||||
if(auto iter = conMap.find(next.value().receiver);
|
if(auto iter = conMap.find(next.value().receiver);
|
||||||
iter != conMap.end()) {
|
iter != conMap.end()) {
|
||||||
|
if(iter->second.sendPkts.size() >= UDPC_QUEUED_PKTS_MAX_SIZE) {
|
||||||
|
UDPC_CHECK_LOG(this,
|
||||||
|
UDPC_LoggingType::UDPC_DEBUG,
|
||||||
|
"Not queueing packet to ",
|
||||||
|
UDPC_atostr((UDPC_HContext)this,
|
||||||
|
next.value().receiver.addr),
|
||||||
|
", port = ",
|
||||||
|
next.value().receiver.port,
|
||||||
|
", connection's queue reached max size");
|
||||||
|
if(sendIter.next()) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
iter->second.sendPkts.push_back(next.value());
|
iter->second.sendPkts.push_back(next.value());
|
||||||
|
if(sendIter.remove()) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_WARNING,
|
UDPC_LoggingType::UDPC_WARNING,
|
||||||
|
@ -332,9 +361,16 @@ void UDPC::Context::update_impl() {
|
||||||
", port = ",
|
", port = ",
|
||||||
next.value().receiver.port,
|
next.value().receiver.port,
|
||||||
" due to connection not existing");
|
" due to connection not existing");
|
||||||
|
if(sendIter.remove()) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(rsize != 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update send (only if triggerSend flag is set)
|
// update send (only if triggerSend flag is set)
|
||||||
|
@ -618,7 +654,7 @@ void UDPC::Context::update_impl() {
|
||||||
else if(bytes < UDPC_MIN_HEADER_SIZE) {
|
else if(bytes < UDPC_MIN_HEADER_SIZE) {
|
||||||
// packet size is too small, invalid packet
|
// packet size is too small, invalid packet
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Received packet is smaller than header, ignoring packet from ",
|
"Received packet is smaller than header, ignoring packet from ",
|
||||||
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -630,7 +666,7 @@ void UDPC::Context::update_impl() {
|
||||||
if(temp != protocolID) {
|
if(temp != protocolID) {
|
||||||
// Invalid protocol id in packet
|
// Invalid protocol id in packet
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Received packet has invalid protocol id, ignoring packet from ",
|
"Received packet has invalid protocol id, ignoring packet from ",
|
||||||
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -652,7 +688,7 @@ void UDPC::Context::update_impl() {
|
||||||
if(isConnect && bytes != UDPC_CON_HEADER_SIZE) {
|
if(isConnect && bytes != UDPC_CON_HEADER_SIZE) {
|
||||||
// invalid packet size
|
// invalid packet size
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Got connect packet of invalid size from ",
|
"Got connect packet of invalid size from ",
|
||||||
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -662,7 +698,7 @@ void UDPC::Context::update_impl() {
|
||||||
} else if (!isConnect && bytes < (int)UDPC_FULL_HEADER_SIZE) {
|
} else if (!isConnect && bytes < (int)UDPC_FULL_HEADER_SIZE) {
|
||||||
// packet is too small
|
// packet is too small
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Got non-connect packet of invalid size from ",
|
"Got non-connect packet of invalid size from ",
|
||||||
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -692,7 +728,7 @@ void UDPC::Context::update_impl() {
|
||||||
std::memcpy(newConnection.peer_pk, recvBuf + UDPC_MIN_HEADER_SIZE,
|
std::memcpy(newConnection.peer_pk, recvBuf + UDPC_MIN_HEADER_SIZE,
|
||||||
crypto_sign_PUBLICKEYBYTES);
|
crypto_sign_PUBLICKEYBYTES);
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_VERBOSE,
|
UDPC_LoggingType::UDPC_INFO,
|
||||||
"Establishing connection with client ",
|
"Establishing connection with client ",
|
||||||
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -726,7 +762,7 @@ void UDPC::Context::update_impl() {
|
||||||
std::memcpy(iter->second.peer_pk, recvBuf + UDPC_MIN_HEADER_SIZE,
|
std::memcpy(iter->second.peer_pk, recvBuf + UDPC_MIN_HEADER_SIZE,
|
||||||
crypto_sign_PUBLICKEYBYTES);
|
crypto_sign_PUBLICKEYBYTES);
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_VERBOSE,
|
UDPC_LoggingType::UDPC_INFO,
|
||||||
"Established connection with server ",
|
"Established connection with server ",
|
||||||
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -753,7 +789,7 @@ void UDPC::Context::update_impl() {
|
||||||
iter->second.peer_pk) != 0) {
|
iter->second.peer_pk) != 0) {
|
||||||
UDPC_CHECK_LOG(
|
UDPC_CHECK_LOG(
|
||||||
this,
|
this,
|
||||||
UDPC_LoggingType::UDPC_VERBOSE,
|
UDPC_LoggingType::UDPC_INFO,
|
||||||
"Failed to verify received packet from",
|
"Failed to verify received packet from",
|
||||||
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -764,7 +800,7 @@ void UDPC::Context::update_impl() {
|
||||||
|
|
||||||
// packet is valid
|
// packet is valid
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Received valid packet from ",
|
"Received valid packet from ",
|
||||||
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
UDPC_atostr((UDPC_HContext)this, receivedData.sin6_addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
|
@ -790,7 +826,7 @@ void UDPC::Context::update_impl() {
|
||||||
iter->second.flags.set(2, iter->second.rtt <= UDPC::GOOD_RTT_LIMIT);
|
iter->second.flags.set(2, iter->second.rtt <= UDPC::GOOD_RTT_LIMIT);
|
||||||
|
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"RTT: ",
|
"RTT: ",
|
||||||
UDPC::durationToFSec(iter->second.rtt) * 1000.0f,
|
UDPC::durationToFSec(iter->second.rtt) * 1000.0f,
|
||||||
" milliseconds");
|
" milliseconds");
|
||||||
|
@ -823,7 +859,7 @@ void UDPC::Context::update_impl() {
|
||||||
if(duration > UDPC::PACKET_TIMEOUT_TIME) {
|
if(duration > UDPC::PACKET_TIMEOUT_TIME) {
|
||||||
if(sentIter->dataSize <= UDPC_FULL_HEADER_SIZE) {
|
if(sentIter->dataSize <= UDPC_FULL_HEADER_SIZE) {
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Timed out packet has no payload (probably "
|
"Timed out packet has no payload (probably "
|
||||||
"heartbeat packet), ignoring it");
|
"heartbeat packet), ignoring it");
|
||||||
sentIter->flags |= 0x8;
|
sentIter->flags |= 0x8;
|
||||||
|
@ -858,7 +894,7 @@ void UDPC::Context::update_impl() {
|
||||||
if((iter->second.ack & (0x80000000 >> (diff - 1))) != 0) {
|
if((iter->second.ack & (0x80000000 >> (diff - 1))) != 0) {
|
||||||
// already received packet
|
// already received packet
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Received packet is already marked as received, ignoring it");
|
"Received packet is already marked as received, ignoring it");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -872,7 +908,7 @@ void UDPC::Context::update_impl() {
|
||||||
if((iter->second.ack & (0x80000000 >> (diff - 1))) != 0) {
|
if((iter->second.ack & (0x80000000 >> (diff - 1))) != 0) {
|
||||||
// already received packet
|
// already received packet
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Received packet is already marked as received, ignoring it");
|
"Received packet is already marked as received, ignoring it");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -887,14 +923,14 @@ void UDPC::Context::update_impl() {
|
||||||
} else {
|
} else {
|
||||||
// already received packet
|
// already received packet
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
"Received packet is already marked as received, ignoring it");
|
"Received packet is already marked as received, ignoring it");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isOutOfOrder) {
|
if(isOutOfOrder) {
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_VERBOSE,
|
UDPC_LoggingType::UDPC_INFO,
|
||||||
"Received packet is out of order");
|
"Received packet is out of order");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,13 +948,7 @@ void UDPC::Context::update_impl() {
|
||||||
recPktInfo.sender.port = ntohs(receivedData.sin6_port);
|
recPktInfo.sender.port = ntohs(receivedData.sin6_port);
|
||||||
recPktInfo.receiver.port = ntohs(socketInfo.sin6_port);
|
recPktInfo.receiver.port = ntohs(socketInfo.sin6_port);
|
||||||
|
|
||||||
if(!receivedPkts.push(recPktInfo)) {
|
|
||||||
UDPC_CHECK_LOG(this,
|
|
||||||
UDPC_LoggingType::UDPC_WARNING,
|
|
||||||
"receivedPkts is full, removing oldest entry to make room");
|
|
||||||
receivedPkts.pop();
|
|
||||||
receivedPkts.push(recPktInfo);
|
receivedPkts.push(recPktInfo);
|
||||||
}
|
|
||||||
} else if(bytes == UDPC_FULL_HEADER_SIZE) {
|
} else if(bytes == UDPC_FULL_HEADER_SIZE) {
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_VERBOSE,
|
UDPC_LoggingType::UDPC_VERBOSE,
|
||||||
|
@ -1228,21 +1258,12 @@ void UDPC_client_initiate_connection(UDPC_HContext ctx, UDPC_ConnectionId connec
|
||||||
addrConIter = insertResult.first;
|
addrConIter = insertResult.first;
|
||||||
}
|
}
|
||||||
addrConIter->second.insert(connectionId);
|
addrConIter->second.insert(connectionId);
|
||||||
UDPC_CHECK_LOG(c, UDPC_LoggingType::UDPC_VERBOSE, "client_initiate_connection: Initiating connection...");
|
UDPC_CHECK_LOG(c, UDPC_LoggingType::UDPC_INFO, "client_initiate_connection: Initiating connection...");
|
||||||
} else {
|
} else {
|
||||||
UDPC_CHECK_LOG(c, UDPC_LoggingType::UDPC_ERROR, "client_initiate_connection: Already connected to peer");
|
UDPC_CHECK_LOG(c, UDPC_LoggingType::UDPC_ERROR, "client_initiate_connection: Already connected to peer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPC_get_queue_send_available(UDPC_HContext ctx) {
|
|
||||||
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
||||||
if(!c) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c->cSendPkts.remaining_capacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDPC_queue_send(UDPC_HContext ctx, UDPC_ConnectionId destinationId,
|
void UDPC_queue_send(UDPC_HContext ctx, UDPC_ConnectionId destinationId,
|
||||||
int isChecked, void *data, uint32_t size) {
|
int isChecked, void *data, uint32_t size) {
|
||||||
if(size == 0 || !data) {
|
if(size == 0 || !data) {
|
||||||
|
@ -1252,15 +1273,6 @@ void UDPC_queue_send(UDPC_HContext ctx, UDPC_ConnectionId destinationId,
|
||||||
UDPC::Context *c = UDPC::verifyContext(ctx);
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
||||||
if(!c) {
|
if(!c) {
|
||||||
return;
|
return;
|
||||||
} else if(c->cSendPkts.full()) {
|
|
||||||
UDPC_CHECK_LOG(c,
|
|
||||||
UDPC_LoggingType::UDPC_ERROR,
|
|
||||||
"Failed to queue packet to ",
|
|
||||||
UDPC_atostr(ctx, destinationId.addr),
|
|
||||||
", port = ",
|
|
||||||
destinationId.port,
|
|
||||||
" because queue is full");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPC_PacketInfo sendInfo = UDPC::get_empty_pinfo();
|
UDPC_PacketInfo sendInfo = UDPC::get_empty_pinfo();
|
||||||
|
@ -1275,6 +1287,15 @@ void UDPC_queue_send(UDPC_HContext ctx, UDPC_ConnectionId destinationId,
|
||||||
c->cSendPkts.push(sendInfo);
|
c->cSendPkts.push(sendInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long UDPC_get_queue_send_current_size(UDPC_HContext ctx) {
|
||||||
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
||||||
|
if(!c) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c->cSendPkts.size();
|
||||||
|
}
|
||||||
|
|
||||||
int UDPC_set_accept_new_connections(UDPC_HContext ctx, int isAccepting) {
|
int UDPC_set_accept_new_connections(UDPC_HContext ctx, int isAccepting) {
|
||||||
UDPC::Context *c = UDPC::verifyContext(ctx);
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
||||||
if(!c) {
|
if(!c) {
|
||||||
|
@ -1386,7 +1407,7 @@ UDPC_LoggingType UDPC_set_logging_type(UDPC_HContext ctx, UDPC_LoggingType loggi
|
||||||
return static_cast<UDPC_LoggingType>(c->loggingType.exchange(loggingType));
|
return static_cast<UDPC_LoggingType>(c->loggingType.exchange(loggingType));
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPC_PacketInfo UDPC_get_received(UDPC_HContext ctx, unsigned int *remaining) {
|
UDPC_PacketInfo UDPC_get_received(UDPC_HContext ctx, unsigned long *remaining) {
|
||||||
UDPC::Context *c = UDPC::verifyContext(ctx);
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
||||||
if(!c) {
|
if(!c) {
|
||||||
return UDPC::get_empty_pinfo();
|
return UDPC::get_empty_pinfo();
|
||||||
|
@ -1399,25 +1420,6 @@ UDPC_PacketInfo UDPC_get_received(UDPC_HContext ctx, unsigned int *remaining) {
|
||||||
return UDPC::get_empty_pinfo();
|
return UDPC::get_empty_pinfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPC_set_received_capacity(UDPC_HContext ctx, unsigned int newCapacity) {
|
|
||||||
if(newCapacity == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
||||||
if(!c) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int status = 0;
|
|
||||||
c->receivedPkts.changeCapacity(newCapacity, &status);
|
|
||||||
if(status == 1) {
|
|
||||||
UDPC_CHECK_LOG(c, UDPC_LoggingType::UDPC_WARNING,
|
|
||||||
"Received Queue: Previous size was truncated to new capacity");
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *UDPC_atostr_cid(UDPC_HContext ctx, UDPC_ConnectionId connectionId) {
|
const char *UDPC_atostr_cid(UDPC_HContext ctx, UDPC_ConnectionId connectionId) {
|
||||||
return UDPC_atostr(ctx, connectionId.addr);
|
return UDPC_atostr(ctx, connectionId.addr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ extern "C" {
|
||||||
struct UDPC_Context;
|
struct UDPC_Context;
|
||||||
typedef struct UDPC_Context *UDPC_HContext;
|
typedef struct UDPC_Context *UDPC_HContext;
|
||||||
|
|
||||||
typedef enum { UDPC_SILENT, UDPC_ERROR, UDPC_WARNING, UDPC_VERBOSE, UDPC_INFO } UDPC_LoggingType;
|
typedef enum { UDPC_SILENT, UDPC_ERROR, UDPC_WARNING, UDPC_INFO, UDPC_VERBOSE, UDPC_DEBUG } UDPC_LoggingType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UDPC_IPV6_ADDR_TYPE addr;
|
UDPC_IPV6_ADDR_TYPE addr;
|
||||||
|
@ -105,11 +105,11 @@ void UDPC_update(UDPC_HContext ctx);
|
||||||
|
|
||||||
void UDPC_client_initiate_connection(UDPC_HContext ctx, UDPC_ConnectionId connectionId);
|
void UDPC_client_initiate_connection(UDPC_HContext ctx, UDPC_ConnectionId connectionId);
|
||||||
|
|
||||||
int UDPC_get_queue_send_available(UDPC_HContext ctx);
|
|
||||||
|
|
||||||
void UDPC_queue_send(UDPC_HContext ctx, UDPC_ConnectionId destinationId,
|
void UDPC_queue_send(UDPC_HContext ctx, UDPC_ConnectionId destinationId,
|
||||||
int isChecked, void *data, uint32_t size);
|
int isChecked, void *data, uint32_t size);
|
||||||
|
|
||||||
|
unsigned long UDPC_get_queue_send_current_size(UDPC_HContext ctx);
|
||||||
|
|
||||||
int UDPC_set_accept_new_connections(UDPC_HContext ctx, int isAccepting);
|
int UDPC_set_accept_new_connections(UDPC_HContext ctx, int isAccepting);
|
||||||
|
|
||||||
int UDPC_drop_connection(UDPC_HContext ctx, UDPC_ConnectionId connectionId, bool dropAllWithAddr);
|
int UDPC_drop_connection(UDPC_HContext ctx, UDPC_ConnectionId connectionId, bool dropAllWithAddr);
|
||||||
|
@ -124,9 +124,7 @@ uint32_t UDPC_set_protocol_id(UDPC_HContext ctx, uint32_t id);
|
||||||
|
|
||||||
UDPC_LoggingType UDPC_set_logging_type(UDPC_HContext ctx, UDPC_LoggingType loggingType);
|
UDPC_LoggingType UDPC_set_logging_type(UDPC_HContext ctx, UDPC_LoggingType loggingType);
|
||||||
|
|
||||||
UDPC_PacketInfo UDPC_get_received(UDPC_HContext ctx, unsigned int *remaining);
|
UDPC_PacketInfo UDPC_get_received(UDPC_HContext ctx, unsigned long *remaining);
|
||||||
|
|
||||||
int UDPC_set_received_capacity(UDPC_HContext ctx, unsigned int newCapacity);
|
|
||||||
|
|
||||||
const char *UDPC_atostr_cid(UDPC_HContext ctx, UDPC_ConnectionId connectionId);
|
const char *UDPC_atostr_cid(UDPC_HContext ctx, UDPC_ConnectionId connectionId);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <UDPConnection.h>
|
#include <UDPConnection.h>
|
||||||
|
|
||||||
|
#define QUEUED_MAX_SIZE 32
|
||||||
|
|
||||||
static const std::regex ipv6_regex_linkonly = std::regex(R"d(fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,})d");
|
static const std::regex ipv6_regex_linkonly = std::regex(R"d(fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,})d");
|
||||||
|
|
||||||
void usage() {
|
void usage() {
|
||||||
|
@ -18,6 +20,7 @@ void usage() {
|
||||||
puts("-cp <port> - connection port (client only)");
|
puts("-cp <port> - connection port (client only)");
|
||||||
puts("-t <tick_count>");
|
puts("-t <tick_count>");
|
||||||
puts("-n - do not add payload to packets");
|
puts("-n - do not add payload to packets");
|
||||||
|
puts("-l (silent|error|warning|info|verbose|debug) - log level, default debug");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
@ -34,6 +37,7 @@ int main(int argc, char **argv) {
|
||||||
const char *connectionPort = nullptr;
|
const char *connectionPort = nullptr;
|
||||||
unsigned int tickLimit = 15;
|
unsigned int tickLimit = 15;
|
||||||
bool noPayload = false;
|
bool noPayload = false;
|
||||||
|
UDPC_LoggingType logLevel = UDPC_LoggingType::UDPC_DEBUG;
|
||||||
while(argc > 0) {
|
while(argc > 0) {
|
||||||
if(std::strcmp(argv[0], "-c") == 0) {
|
if(std::strcmp(argv[0], "-c") == 0) {
|
||||||
isClient = true;
|
isClient = true;
|
||||||
|
@ -58,6 +62,26 @@ int main(int argc, char **argv) {
|
||||||
} else if(std::strcmp(argv[0], "-n") == 0) {
|
} else if(std::strcmp(argv[0], "-n") == 0) {
|
||||||
noPayload = true;
|
noPayload = true;
|
||||||
puts("Disabling sending payload");
|
puts("Disabling sending payload");
|
||||||
|
} else if(std::strcmp(argv[0], "-l") == 0) {
|
||||||
|
--argc; ++argv;
|
||||||
|
if(std::strcmp(argv[0], "silent") == 0) {
|
||||||
|
logLevel = UDPC_LoggingType::UDPC_SILENT;
|
||||||
|
} else if(std::strcmp(argv[0], "error") == 0) {
|
||||||
|
logLevel = UDPC_LoggingType::UDPC_ERROR;
|
||||||
|
} else if(std::strcmp(argv[0], "warning") == 0) {
|
||||||
|
logLevel = UDPC_LoggingType::UDPC_WARNING;
|
||||||
|
} else if(std::strcmp(argv[0], "info") == 0) {
|
||||||
|
logLevel = UDPC_LoggingType::UDPC_INFO;
|
||||||
|
} else if(std::strcmp(argv[0], "verbose") == 0) {
|
||||||
|
logLevel = UDPC_LoggingType::UDPC_VERBOSE;
|
||||||
|
} else if(std::strcmp(argv[0], "debug") == 0) {
|
||||||
|
logLevel = UDPC_LoggingType::UDPC_DEBUG;
|
||||||
|
} else {
|
||||||
|
printf("ERROR: invalid argument \"%s\", expected "
|
||||||
|
"silent|error|warning|info|verbose|debug", argv[0]);
|
||||||
|
usage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("ERROR: invalid argument \"%s\"\n", argv[0]);
|
printf("ERROR: invalid argument \"%s\"\n", argv[0]);
|
||||||
usage();
|
usage();
|
||||||
|
@ -106,10 +130,11 @@ int main(int argc, char **argv) {
|
||||||
puts("ERROR: context is NULL");
|
puts("ERROR: context is NULL");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
UDPC_set_logging_type(context, UDPC_LoggingType::UDPC_INFO);
|
UDPC_set_logging_type(context, logLevel);
|
||||||
unsigned int tick = 0;
|
unsigned int tick = 0;
|
||||||
unsigned int temp = 0;
|
unsigned int temp = 0;
|
||||||
unsigned int temp2, temp3;
|
unsigned int temp2, temp3;
|
||||||
|
unsigned long size;
|
||||||
UDPC_ConnectionId *list = nullptr;
|
UDPC_ConnectionId *list = nullptr;
|
||||||
std::vector<unsigned int> sendIds;
|
std::vector<unsigned int> sendIds;
|
||||||
UDPC_PacketInfo received;
|
UDPC_PacketInfo received;
|
||||||
|
@ -126,7 +151,8 @@ int main(int argc, char **argv) {
|
||||||
} else if(sendIds.size() > temp) {
|
} else if(sendIds.size() > temp) {
|
||||||
sendIds.resize(temp);
|
sendIds.resize(temp);
|
||||||
}
|
}
|
||||||
temp2 = UDPC_get_queue_send_available(context);
|
size = UDPC_get_queue_send_current_size(context);
|
||||||
|
temp2 = size < QUEUED_MAX_SIZE ? QUEUED_MAX_SIZE - size : 0;
|
||||||
for(unsigned int i = 0; i < temp2; ++i) {
|
for(unsigned int i = 0; i < temp2; ++i) {
|
||||||
temp3 = htonl(sendIds[i % temp]++);
|
temp3 = htonl(sendIds[i % temp]++);
|
||||||
UDPC_queue_send(context, list[i % temp], 0, &temp3, sizeof(unsigned int));
|
UDPC_queue_send(context, list[i % temp], 0, &temp3, sizeof(unsigned int));
|
||||||
|
@ -134,14 +160,14 @@ int main(int argc, char **argv) {
|
||||||
UDPC_free_list_connected(list);
|
UDPC_free_list_connected(list);
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
received = UDPC_get_received(context, &temp);
|
received = UDPC_get_received(context, &size);
|
||||||
if(received.dataSize == sizeof(unsigned int)) {
|
if(received.dataSize == sizeof(unsigned int)) {
|
||||||
if((received.flags & 0x8) != 0) {
|
if((received.flags & 0x8) != 0) {
|
||||||
temp2 = ntohl(*((unsigned int*)received.data));
|
temp2 = ntohl(*((unsigned int*)received.data));
|
||||||
printf("Got out of order, data = %u\n", temp2);
|
printf("Got out of order, data = %u\n", temp2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (temp > 0);
|
} while (size > 0);
|
||||||
}
|
}
|
||||||
if(tick++ > tickLimit) {
|
if(tick++ > tickLimit) {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue