Some WIP impl of receiving packet handling
This commit is contained in:
parent
bf27c328a6
commit
1e0f631ab2
2 changed files with 103 additions and 3 deletions
|
@ -6,6 +6,7 @@
|
|||
#define UDPC_GOOD_MODE_SEND_INTERVAL (1.0f / 30.0f)
|
||||
#define UDPC_BAD_MODE_SEND_INTERVAL (1.0f / 10.0f)
|
||||
#define UDPC_SENT_PKTS_MAX_SIZE 33
|
||||
#define UDPC_QUEUED_PKTS_MAX_SIZE 32
|
||||
|
||||
#define UDPC_ID_CONNECT 0x80000000
|
||||
#define UDPC_ID_PING 0x40000000
|
||||
|
@ -18,6 +19,7 @@
|
|||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
#include <random>
|
||||
|
||||
#include "TSQueue.hpp"
|
||||
#include "UDPConnection.h"
|
||||
|
@ -27,8 +29,14 @@ namespace UDPC {
|
|||
static uint32_t LOCAL_ADDR = 0;
|
||||
static const auto INIT_PKT_INTERVAL_DT = std::chrono::seconds(5);
|
||||
static const auto HEARTBEAT_PKT_INTERVAL_DT = std::chrono::milliseconds(150);
|
||||
static const auto PACKET_TIMEOUT_TIME = std::chrono::seconds(1);
|
||||
|
||||
struct Context;
|
||||
|
||||
struct ConnectionData {
|
||||
ConnectionData();
|
||||
ConnectionData(bool isServer, Context *ctx);
|
||||
|
||||
/*
|
||||
* 0 - trigger send
|
||||
* 1 - is good mode
|
||||
|
@ -59,9 +67,11 @@ struct Context {
|
|||
Context(bool isThreaded);
|
||||
|
||||
uint_fast32_t _contextIdentifier;
|
||||
char recvBuf[UDPC_PACKET_MAX_SIZE];
|
||||
/*
|
||||
* 0 - is threaded
|
||||
* 1 - is client
|
||||
* 2 - is accepting new connections
|
||||
*/
|
||||
std::bitset<32> flags;
|
||||
std::atomic_bool isAcceptNewConnections;
|
||||
|
@ -73,9 +83,13 @@ struct Context {
|
|||
struct sockaddr_in socketInfo;
|
||||
|
||||
std::chrono::steady_clock::time_point lastUpdated;
|
||||
// ipv4 address to ConnectionData
|
||||
std::unordered_map<uint32_t, ConnectionData> conMap;
|
||||
// id to ipv4 address
|
||||
std::unordered_map<uint32_t, uint32_t> idMap;
|
||||
|
||||
std::default_random_engine rng_engine;
|
||||
|
||||
}; // struct Context
|
||||
|
||||
Context *verifyContext(void *ctx);
|
||||
|
@ -92,6 +106,8 @@ bool isBigEndian();
|
|||
void preparePacket(char *data, uint32_t protocolID, uint32_t conID,
|
||||
uint32_t rseq, uint32_t ack, uint32_t *seqID, int flags);
|
||||
|
||||
uint32_t generateConnectionID(Context &ctx);
|
||||
|
||||
} // namespace UDPC
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,14 +7,36 @@
|
|||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
UDPC::ConnectionData::ConnectionData() :
|
||||
flags(),
|
||||
sentPkts(),
|
||||
sendPkts(UDPC_QUEUED_PKTS_MAX_SIZE),
|
||||
priorityPkts(UDPC_QUEUED_PKTS_MAX_SIZE),
|
||||
received(std::chrono::steady_clock::now()),
|
||||
sent(std::chrono::steady_clock::now())
|
||||
{
|
||||
}
|
||||
|
||||
UDPC::ConnectionData::ConnectionData(bool isServer, Context *ctx) :
|
||||
UDPC::ConnectionData::ConnectionData()
|
||||
{
|
||||
if(isServer) {
|
||||
flags.set(0);
|
||||
flags.set(3);
|
||||
id = UDPC::generateConnectionID(*ctx);
|
||||
flags.set(4);
|
||||
}
|
||||
}
|
||||
|
||||
UDPC::Context::Context(bool isThreaded)
|
||||
: _contextIdentifier(UDPC_CONTEXT_IDENTIFIER), flags(),
|
||||
isAcceptNewConnections(true), protocolID(UDPC_DEFAULT_PROTOCOL_ID),
|
||||
#ifndef NDEBUG
|
||||
loggingType(INFO)
|
||||
loggingType(INFO),
|
||||
#else
|
||||
loggingType(WARNING)
|
||||
loggingType(WARNING),
|
||||
#endif
|
||||
rng_engine()
|
||||
{
|
||||
if(isThreaded) {
|
||||
flags.set(0);
|
||||
|
@ -29,6 +51,8 @@ UDPC::Context::Context(bool isThreaded)
|
|||
UDPC::LOCAL_ADDR = 0x0100007F;
|
||||
}
|
||||
}
|
||||
|
||||
rng_engine.seed(std::chrono::system_clock::now().time_since_epoch().count());
|
||||
}
|
||||
|
||||
UDPC::Context *UDPC::verifyContext(void *ctx) {
|
||||
|
@ -84,6 +108,15 @@ void UDPC::preparePacket(char *data, uint32_t protocolID, uint32_t conID,
|
|||
std::memcpy(data + 16, &temp, 4);
|
||||
}
|
||||
|
||||
uint32_t UDPC::generateConnectionID(Context &ctx) {
|
||||
auto dist = std::uniform_int_distribution<uint32_t>(0, 0xFFFFFFFF);
|
||||
uint32_t id = dist(ctx.rng_engine);
|
||||
while(ctx.idMap.find(id) != ctx.idMap.end()) {
|
||||
id = dist(ctx.rng_engine);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void *UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient) {
|
||||
UDPC::Context *ctx = new UDPC::Context(false);
|
||||
|
||||
|
@ -423,7 +456,58 @@ void UDPC_update(void *ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO receive packet
|
||||
// receive packet
|
||||
#if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
struct sockaddr_in receivedData;
|
||||
socklen_t receivedDataSize = sizeof(receivedData);
|
||||
int bytes = recvfrom(
|
||||
c->socketHandle,
|
||||
c->recvBuf,
|
||||
UDPC_PACKET_MAX_SIZE,
|
||||
0,
|
||||
(struct sockaddr*) &receivedData,
|
||||
&receivedDataSize);
|
||||
|
||||
if(bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
|
||||
// no packet was received
|
||||
return;
|
||||
} else if(bytes < 20) {
|
||||
// packet size is too small, invalid packet
|
||||
// TODO log this
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t temp = ntohl(*((uint32_t*)c->recvBuf));
|
||||
if(temp != c->protocolID) {
|
||||
// Invalid protocol id in packet
|
||||
// TODO log this
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t conID = ntohl(*((uint32_t*)(c->recvBuf + 4)));
|
||||
uint32_t seqID = ntohl(*((uint32_t*)(c->recvBuf + 8)));
|
||||
uint32_t rseq = ntohl(*((uint32_t*)(c->recvBuf + 12)));
|
||||
uint32_t ack = htonl(*((uint32_t*)(c->recvBuf + 16)));
|
||||
|
||||
bool isConnect = conID & UDPC_ID_CONNECT;
|
||||
bool isPing = conID & UDPC_ID_PING;
|
||||
bool isNotRecChecked = conID & UDPC_ID_NO_REC_CHK;
|
||||
bool isResending = conID & UDPC_ID_RESENDING;
|
||||
conID &= 0x0FFFFFFF;
|
||||
|
||||
if(isConnect && c->flags.test(2)) {
|
||||
// is connect packet and is accepting new connections
|
||||
if(!c->flags.test(1)
|
||||
&& c->conMap.find(receivedData.sin_addr.s_addr) == c->conMap.end()) {
|
||||
// is receiving as server, connection did not already exist
|
||||
// TODO log establishing connection with client peer
|
||||
UDPC::ConnectionData newConnection(true, c);
|
||||
// TODO update idMap and conMap with new CD
|
||||
// TODO impl establish connection with client peer as server
|
||||
}
|
||||
}
|
||||
|
||||
// TODO impl
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue