diff --git a/cpp_impl/src/UDPC_Defines.hpp b/cpp_impl/src/UDPC_Defines.hpp index 0f3c4fd..a59617d 100644 --- a/cpp_impl/src/UDPC_Defines.hpp +++ b/cpp_impl/src/UDPC_Defines.hpp @@ -8,6 +8,7 @@ #define UDPC_SENT_PKTS_MAX_SIZE 33 #define UDPC_QUEUED_PKTS_MAX_SIZE 32 #define UDPC_GOOD_RTT_LIMIT_SEC 0.25f +#define UDPC_PACKET_TIMEOUT_SEC 1.0f #define UDPC_ID_CONNECT 0x80000000 #define UDPC_ID_PING 0x40000000 diff --git a/cpp_impl/src/UDPConnection.cpp b/cpp_impl/src/UDPConnection.cpp index 5485df2..64961cf 100644 --- a/cpp_impl/src/UDPConnection.cpp +++ b/cpp_impl/src/UDPConnection.cpp @@ -41,7 +41,7 @@ UDPC::ConnectionData::ConnectionData() void UDPC::ConnectionData::cleanupSentPkts() { uint32_t id; while(sentPkts.size() > UDPC_SENT_PKTS_MAX_SIZE) { - id = *((uint32_t*)(sentPkts.front().data + 8)); + id = ntohl(*((uint32_t*)(sentPkts.front().data + 8))); sentInfoMap.erase(id); sentPkts.pop_front(); } @@ -401,7 +401,7 @@ void UDPC_update(void *ctx) { pInfo.receiver = iter->first; pInfo.senderPort = c->socketInfo.sin_port; pInfo.receiverPort = iter->second.port; - *((uint32_t*)(pInfo.data + 8)) = iter->second.lseq - 1; + *((uint32_t*)(pInfo.data + 8)) = htonl(iter->second.lseq - 1); iter->second.sentPkts.push_back(std::move(pInfo)); iter->second.cleanupSentPkts(); @@ -471,7 +471,7 @@ void UDPC_update(void *ctx) { sentPInfo.receiver = iter->first; sentPInfo.senderPort = c->socketInfo.sin_port; sentPInfo.receiverPort = iter->second.port; - *((uint32_t*)(sentPInfo.data + 8)) = iter->second.lseq - 1; + *((uint32_t*)(sentPInfo.data + 8)) = htonl(iter->second.lseq - 1); iter->second.sentPkts.push_back(std::move(pInfo)); iter->second.cleanupSentPkts(); @@ -566,7 +566,7 @@ void UDPC_update(void *ctx) { // update rtt for(auto sentIter = iter->second.sentPkts.rbegin(); sentIter != iter->second.sentPkts.rend(); ++sentIter) { - uint32_t id = *((uint32_t*)(sentIter->data + 8)); + uint32_t id = ntohl(*((uint32_t*)(sentIter->data + 8))); if(id == rseq) { auto sentInfoIter = iter->second.sentInfoMap.find(id); assert(sentInfoIter != iter->second.sentInfoMap.end() @@ -586,7 +586,46 @@ void UDPC_update(void *ctx) { } iter->second.received = now; - // TODO impl check pkt timeout + + // check pkt timeout + --rseq; + for(; ack != 0; ack = ack << 1) { + if((ack & 0x80000000) != 0) { + --rseq; + continue; + } + + // pkt not received yet, find it in sent to check if it timed out + for(auto sentIter = iter->second.sentPkts.rbegin(); sentIter != iter->second.sentPkts.rend(); ++sentIter) { + uint32_t sentID = ntohl(*((uint32_t*)(sentIter->data + 8))); + if(sentID == rseq) { + if((sentIter->flags & 0x4) != 0 || (sentIter->flags & 0x8) != 0) { + // already resent or not rec-checked pkt + break; + } + auto sentInfoIter = iter->second.sentInfoMap.find(sentID); + assert(sentInfoIter != iter->second.sentInfoMap.end() + && "Every entry in sentPkts must have a corresponding entry in sentInfoMap"); + float seconds = UDPC::durationToFSec(sentInfoIter->second->sentTime, now); + if(seconds > UDPC_PACKET_TIMEOUT_SEC) { + if(sentIter->dataSize <= 20) { + // TODO log error: timed out packet has no data + sentIter->flags |= 0x8; + break; + } + + UDPC_PacketInfo resendingData; + resendingData.dataSize = sentIter->dataSize - 20; + std::memcpy(resendingData.data, sentIter->data + 20, resendingData.dataSize); + resendingData.flags = 0; + iter->second.priorityPkts.push(resendingData); + } + break; + } + } + + --rseq; + } // TODO impl }