Expose ConnectionId to C interface, fixes

Removed UDPC:ConnectionIdentifier from UDPC_Defines.hpp and added
ConnectionId to UDPConnection.h, and replaced/fixed instances of the
older type.
This commit is contained in:
Stephen Seo 2019-09-03 12:06:46 +09:00
parent 0167c4953b
commit 150deb7e5c
3 changed files with 58 additions and 101 deletions

View file

@ -55,35 +55,8 @@ struct SentPktInfo {
std::chrono::steady_clock::time_point sentTime;
};
struct ConnectionIdentifier {
ConnectionIdentifier();
ConnectionIdentifier(uint32_t addr, uint16_t port);
// copy
ConnectionIdentifier(const ConnectionIdentifier& other) = default;
ConnectionIdentifier& operator =(const ConnectionIdentifier& other) = default;
// move
ConnectionIdentifier(ConnectionIdentifier&& other) = default;
ConnectionIdentifier& operator =(ConnectionIdentifier&& other) = default;
uint64_t id;
/// expects address to be in network byte order (big-endian)
void setAddr(uint32_t addr);
/// expects port to be in native order (not network byte order)
void setPort(uint16_t port);
/// returns address as a 4 byte unsigned int in network byte order (big-endian)
uint32_t getAddr() const;
/// returns port as a 2 byte unsigned int in native order (not network byte order)
uint16_t getPort() const;
bool operator ==(const ConnectionIdentifier& other) const;
struct Hasher {
std::size_t operator()(const ConnectionIdentifier& key) const;
};
struct ConnectionIdHasher {
std::size_t operator()(const UDPC_ConnectionId& key) const;
};
struct ConnectionData {
@ -262,12 +235,12 @@ public:
struct sockaddr_in socketInfo;
std::chrono::steady_clock::time_point lastUpdated;
// ipv4 address and port (as ConnectionIdentifier) to ConnectionData
std::unordered_map<ConnectionIdentifier, ConnectionData, ConnectionIdentifier::Hasher> conMap;
// ipv4 address to all connected ConnectionIdentifiers
std::unordered_map<uint32_t, std::unordered_set<ConnectionIdentifier, ConnectionIdentifier::Hasher> > addrConMap;
// id to ipv4 address and port (as ConnectionIdentifier)
std::unordered_map<uint32_t, ConnectionIdentifier> idMap;
// ipv4 address and port (as UDPC_ConnectionId) to ConnectionData
std::unordered_map<UDPC_ConnectionId, ConnectionData, ConnectionIdHasher> conMap;
// ipv4 address to all connected UDPC_ConnectionId
std::unordered_map<uint32_t, std::unordered_set<UDPC_ConnectionId, ConnectionIdHasher> > addrConMap;
// id to ipv4 address and port (as UDPC_ConnectionId)
std::unordered_map<uint32_t, UDPC_ConnectionId> idMap;
std::default_random_engine rng_engine;
@ -297,4 +270,6 @@ float timePointsToFSec(
} // namespace UDPC
bool operator ==(const UDPC_ConnectionId& a, const UDPC_ConnectionId& b);
#endif

View file

@ -14,39 +14,12 @@ id(0),
sentTime(std::chrono::steady_clock::now())
{}
UDPC::ConnectionIdentifier::ConnectionIdentifier() :
id(0)
{}
UDPC::ConnectionIdentifier::ConnectionIdentifier(uint32_t addr, uint16_t port) :
UDPC::ConnectionIdentifier::ConnectionIdentifier()
{
*((uint32_t*)&id) = addr;
*((uint16_t*)(((unsigned char*)&id) + 4)) = port;
std::size_t UDPC::ConnectionIdHasher::operator()(const UDPC_ConnectionId& key) const {
return std::hash<uint32_t>()(key.addr) ^ (std::hash<uint16_t>()(key.port) << 1);
}
void UDPC::ConnectionIdentifier::setAddr(uint32_t addr) {
*((uint32_t*)&id) = addr;
}
void UDPC::ConnectionIdentifier::setPort(uint16_t port) {
*((uint16_t*)(((unsigned char*)&id) + 4)) = port;
}
uint32_t UDPC::ConnectionIdentifier::getAddr() const {
return *((uint32_t*)&id);
}
uint16_t UDPC::ConnectionIdentifier::getPort() const {
return *((uint16_t*)(((unsigned char*)&id) + 4));
}
bool UDPC::ConnectionIdentifier::operator==(const ConnectionIdentifier& other) const {
return id == other.id;
}
std::size_t UDPC::ConnectionIdentifier::Hasher::operator()(const ConnectionIdentifier& key) const {
return std::hash<uint64_t>()(key.id);
bool operator ==(const UDPC_ConnectionId& a, const UDPC_ConnectionId& b) {
return a.addr == b.addr && a.port == b.port;
}
UDPC::ConnectionData::ConnectionData() :
@ -199,6 +172,10 @@ float UDPC::timePointsToFSec(
* (float)decltype(dt)::period::num / (float)decltype(dt)::period::den;
}
UDPC_ConnectionId UDPC_create_id(uint32_t addr, uint16_t port) {
return UDPC_ConnectionId{addr, port};
}
UDPC_HContext UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient) {
UDPC::Context *ctx = new UDPC::Context(false);
ctx->flags.set(1, isClient);
@ -284,7 +261,7 @@ void UDPC_update(UDPC_HContext ctx) {
std::chrono::steady_clock::duration temp_dt_fs;
{
// check timed out, check good/bad mode with rtt, remove timed out
std::vector<UDPC::ConnectionIdentifier> removed;
std::vector<UDPC_ConnectionId> removed;
for(auto iter = c->conMap.begin(); iter != c->conMap.end(); ++iter) {
temp_dt_fs = now - iter->second.received;
if(temp_dt_fs >= UDPC::CONNECTION_TIMEOUT) {
@ -352,7 +329,7 @@ void UDPC_update(UDPC_HContext ctx) {
}
}
for(auto iter = removed.begin(); iter != removed.end(); ++iter) {
auto addrConIter = c->addrConMap.find(iter->getAddr());
auto addrConIter = c->addrConMap.find(iter->addr);
assert(addrConIter != c->addrConMap.end()
&& "addrConMap must have an entry for a current connection");
auto addrConSetIter = addrConIter->second.find(*iter);
@ -500,10 +477,10 @@ void UDPC_update(UDPC_HContext ctx) {
}
UDPC_PacketInfo pInfo{{0}, 0, 0, 0, 0, 0, 0};
pInfo.sender = UDPC::LOCAL_ADDR;
pInfo.receiver = iter->first.getAddr();
pInfo.senderPort = c->socketInfo.sin_port;
pInfo.receiverPort = iter->second.port;
pInfo.sender.addr = UDPC::LOCAL_ADDR;
pInfo.receiver.addr = iter->first.addr;
pInfo.sender.port = c->socketInfo.sin_port;
pInfo.receiver.port = iter->second.port;
*((uint32_t*)(pInfo.data + 8)) = iter->second.lseq - 1;
iter->second.sentPkts.push_back(std::move(pInfo));
@ -564,10 +541,10 @@ void UDPC_update(UDPC_HContext ctx) {
std::memcpy(sentPInfo.data, buf.get(), 20 + pInfo.dataSize);
sentPInfo.flags = 0;
sentPInfo.dataSize = 20 + pInfo.dataSize;
sentPInfo.sender = UDPC::LOCAL_ADDR;
sentPInfo.receiver = iter->first.getAddr();
sentPInfo.senderPort = c->socketInfo.sin_port;
sentPInfo.receiverPort = iter->second.port;
sentPInfo.sender.addr = UDPC::LOCAL_ADDR;
sentPInfo.receiver.addr = iter->first.addr;
sentPInfo.sender.port = c->socketInfo.sin_port;
sentPInfo.receiver.port = iter->second.port;
iter->second.sentPkts.push_back(std::move(pInfo));
iter->second.cleanupSentPkts();
@ -576,10 +553,10 @@ void UDPC_update(UDPC_HContext ctx) {
UDPC_PacketInfo sentPInfo;
sentPInfo.flags = 0x4;
sentPInfo.dataSize = 0;
sentPInfo.sender = UDPC::LOCAL_ADDR;
sentPInfo.receiver = iter->first.getAddr();
sentPInfo.senderPort = c->socketInfo.sin_port;
sentPInfo.receiverPort = iter->second.port;
sentPInfo.sender.addr = UDPC::LOCAL_ADDR;
sentPInfo.receiver.addr = iter->first.addr;
sentPInfo.sender.port = c->socketInfo.sin_port;
sentPInfo.receiver.port = iter->second.port;
*((uint32_t*)(sentPInfo.data + 8)) = iter->second.lseq - 1;
iter->second.sentPkts.push_back(std::move(pInfo));
@ -644,7 +621,7 @@ void UDPC_update(UDPC_HContext ctx) {
bool isResending = conID & UDPC_ID_RESENDING;
conID &= 0x0FFFFFFF;
UDPC::ConnectionIdentifier identifier(receivedData.sin_addr.s_addr, ntohs(receivedData.sin_port));
UDPC_ConnectionId identifier{receivedData.sin_addr.s_addr, ntohs(receivedData.sin_port)};
if(isConnect && c->flags.test(2)) {
// is connect packet and is accepting new connections
@ -663,12 +640,12 @@ void UDPC_update(UDPC_HContext ctx) {
c->idMap.insert(std::make_pair(newConnection.id, identifier));
c->conMap.insert(std::make_pair(identifier, std::move(newConnection)));
auto addrConIter = c->addrConMap.find(identifier.getAddr());
auto addrConIter = c->addrConMap.find(identifier.addr);
if(addrConIter == c->addrConMap.end()) {
auto insertResult = c->addrConMap.insert(
std::make_pair(
identifier.getAddr(),
std::unordered_set<UDPC::ConnectionIdentifier, UDPC::ConnectionIdentifier::Hasher>{}
identifier.addr,
std::unordered_set<UDPC_ConnectionId, UDPC::ConnectionIdHasher>{}
));
assert(insertResult.second
&& "Must successfully insert into addrConMap");
@ -846,10 +823,10 @@ void UDPC_update(UDPC_HContext ctx) {
| (isPing ? 0x2 : 0)
| (isNotRecChecked ? 0x4 : 0)
| (isResending ? 0x8 : 0);
recPktInfo.sender = receivedData.sin_addr.s_addr;
recPktInfo.receiver = UDPC::LOCAL_ADDR;
recPktInfo.senderPort = receivedData.sin_port;
recPktInfo.receiverPort = c->socketInfo.sin_port;
recPktInfo.sender.addr = receivedData.sin_addr.s_addr;
recPktInfo.receiver.addr = UDPC::LOCAL_ADDR;
recPktInfo.sender.port = receivedData.sin_port;
recPktInfo.receiver.port = c->socketInfo.sin_port;
if(iter->second.receivedPkts.size() == iter->second.receivedPkts.capacity()) {
c->log(
@ -873,7 +850,7 @@ void UDPC_client_initiate_connection(UDPC_HContext ctx, uint32_t addr, uint16_t
}
UDPC::ConnectionData newCon(false, c);
UDPC::ConnectionIdentifier identifier(addr, port);
UDPC_ConnectionId identifier{addr, port};
// TODO make thread safe by using mutex
c->conMap.insert(std::make_pair(identifier, std::move(newCon)));
@ -881,7 +858,7 @@ void UDPC_client_initiate_connection(UDPC_HContext ctx, uint32_t addr, uint16_t
if(addrConIter == c->addrConMap.end()) {
auto insertResult = c->addrConMap.insert(std::make_pair(
addr,
std::unordered_set<UDPC::ConnectionIdentifier, UDPC::ConnectionIdentifier::Hasher>{}
std::unordered_set<UDPC_ConnectionId, UDPC::ConnectionIdHasher>{}
));
assert(insertResult.second);
addrConIter = insertResult.first;
@ -895,7 +872,7 @@ int UDPC_get_queue_send_available(UDPC_HContext ctx, uint32_t addr, uint16_t por
return 0;
}
UDPC::ConnectionIdentifier identifier(addr, port);
UDPC_ConnectionId identifier{addr, port};
auto iter = c->conMap.find(identifier);
if(iter != c->conMap.end()) {
@ -916,7 +893,7 @@ void UDPC_queue_send(UDPC_HContext ctx, uint32_t destAddr, uint16_t destPort,
return;
}
UDPC::ConnectionIdentifier identifier(destAddr, destPort);
UDPC_ConnectionId identifier{destAddr, destPort};
auto iter = c->conMap.find(identifier);
if(iter == c->conMap.end()) {
@ -930,10 +907,10 @@ void UDPC_queue_send(UDPC_HContext ctx, uint32_t destAddr, uint16_t destPort,
UDPC_PacketInfo sendInfo;
std::memcpy(sendInfo.data, data, size);
sendInfo.dataSize = size;
sendInfo.sender = UDPC::LOCAL_ADDR;
sendInfo.senderPort = c->socketInfo.sin_port;
sendInfo.receiver = destAddr;
sendInfo.receiverPort = iter->second.port;
sendInfo.sender.addr = UDPC::LOCAL_ADDR;
sendInfo.sender.port = c->socketInfo.sin_port;
sendInfo.receiver.addr = destAddr;
sendInfo.receiver.port = iter->second.port;
sendInfo.flags = (isChecked ? 0x0 : 0x4);
iter->second.sendPkts.push(sendInfo);
@ -953,7 +930,7 @@ int UDPC_drop_connection(UDPC_HContext ctx, uint32_t addr, uint16_t port) {
return 0;
}
UDPC::ConnectionIdentifier identifier(addr, port);
UDPC_ConnectionId identifier{addr, port};
auto iter = c->conMap.find(identifier);
if(iter != c->conMap.end()) {

View file

@ -50,6 +50,11 @@ typedef struct UDPC_Context *UDPC_HContext;
typedef enum { SILENT, ERROR, WARNING, VERBOSE, INFO } UDPC_LoggingType;
typedef struct {
uint32_t addr;
uint16_t port;
} UDPC_ConnectionId;
typedef struct {
// id is stored at offset 8, size 4 (uint32_t) even for "empty" PktInfos
char data[UDPC_PACKET_MAX_SIZE];
@ -61,12 +66,12 @@ typedef struct {
*/
uint32_t flags;
uint16_t dataSize; // zero if invalid
uint32_t sender;
uint32_t receiver;
uint16_t senderPort;
uint16_t receiverPort;
UDPC_ConnectionId sender;
UDPC_ConnectionId receiver;
} UDPC_PacketInfo;
UDPC_ConnectionId UDPC_create_id(uint32_t addr, uint16_t port);
/// listenPort must be in native byte order, listenAddr must be in network byte order (big-endian)
UDPC_HContext UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient);
/// listenPort must be in native byte order, listenAddr must be in network byte order (big-endian)