]> git.seodisparate.com - UDPConnection/commitdiff
Impl storing received packet
authorStephen Seo <seo.disparate@gmail.com>
Tue, 27 Aug 2019 04:03:38 +0000 (13:03 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Tue, 27 Aug 2019 04:03:38 +0000 (13:03 +0900)
cpp_impl/src/TSQueue.hpp
cpp_impl/src/UDPC_Defines.hpp
cpp_impl/src/UDPConnection.cpp

index 8b7d65c9c214bb34a2ef9398234c7f79f2f41588..947f76ccece948ebd37b7a61c98c013e5701a3f9 100644 (file)
@@ -28,6 +28,7 @@ class TSQueue {
     void clear();
     void changeCapacity(unsigned int newCapacity);
     unsigned int size();
+    unsigned int capacity();
     bool empty();
 
   private:
@@ -114,6 +115,13 @@ unsigned int TSQueue<T>::size() {
     return size;
 }
 
+template <typename T>
+unsigned int TSQueue<T>::capacity() {
+    std::lock_guard<std::mutex> lock(mutex);
+    unsigned int capacity = rb.getCapacity();
+    return capacity;
+}
+
 template <typename T>
 bool TSQueue<T>::empty() {
     // No lock required, since this is calling size() that uses a lock
index a59617d67ca2292e4bc516d3cb0839733ee688ee..52ffb4460edd45f302075c4254349b14231d7ec8 100644 (file)
@@ -82,6 +82,7 @@ struct ConnectionData {
     std::deque<UDPC_PacketInfo> sentPkts;
     TSQueue<UDPC_PacketInfo> sendPkts;
     TSQueue<UDPC_PacketInfo> priorityPkts;
+    TSQueue<UDPC_PacketInfo> receivedPkts;
     // pkt id to pkt shared_ptr
     std::unordered_map<uint32_t, SentPktInfo::Ptr> sentInfoMap;
     std::chrono::steady_clock::time_point received;
index 64961cf394f92001ce93814ac47896c8efb2a930..dddd7086b07d74059c126028c28dd74371fb6ba6 100644 (file)
@@ -627,7 +627,74 @@ void UDPC_update(void *ctx) {
         --rseq;
     }
 
-    // TODO impl
+    // calculate sequence and ack
+    bool isOutOfOrder = false;
+    uint32_t diff = 0;
+    if(seqID > iter->second.rseq) {
+        diff = seqID - iter->second.rseq;
+        if(diff <= 0x7FFFFFFF) {
+            // sequence is more recent
+            iter->second.rseq = seqID;
+            iter->second.ack = (iter->second.ack >> diff) | 0x80000000;
+        } else {
+            // sequence is older, recalc diff
+            diff = 0xFFFFFFFF - seqID + 1 + iter->second.rseq;
+            if((iter->second.ack & (0x80000000 >> (diff - 1))) != 0) {
+                // already received packet
+                // TODO log that already received packet is ignored
+                return;
+            }
+            iter->second.ack |= 0x80000000 >> (diff - 1);
+            isOutOfOrder = true;
+        }
+    } else if(seqID < iter->second.rseq) {
+        diff = iter->second.rseq - seqID;
+        if(diff <= 0x7FFFFFFF) {
+            // sequence is older
+            if((iter->second.ack & (0x80000000 >> (diff - 1))) != 0) {
+                // already received packet
+                // TODO log that already received packet is ignored
+                return;
+            }
+            iter->second.ack |= 0x80000000 >> (diff - 1);
+            isOutOfOrder = true;
+        } else {
+            // sequence is more recent, recalc diff
+            diff = 0xFFFFFFFF - iter->second.rseq + 1 + seqID;
+            iter->second.rseq = seqID;
+            iter->second.ack = (iter->second.ack >> diff) | 0x80000000;
+        }
+    } else {
+        // already received packet
+        // TODO log that already received packet is ignored
+        return;
+    }
+
+    // TODO log that received packet is out of order
+
+    if(bytes > 20) {
+        UDPC_PacketInfo recPktInfo;
+        std::memcpy(recPktInfo.data, c->recvBuf, bytes);
+        recPktInfo.dataSize = bytes;
+        recPktInfo.flags =
+            (isConnect ? 0x1 : 0)
+            | (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;
+
+        if(iter->second.receivedPkts.size() == iter->second.receivedPkts.capacity()) {
+            // TODO log that receivedPkts is full, so removed an entry for a new one
+            iter->second.receivedPkts.pop();
+        }
+
+        iter->second.receivedPkts.push(recPktInfo);
+    } else if(bytes == 20) {
+        // TODO log that packet had no payload
+    }
 }
 
 int UDPC_get_queue_send_available(void *ctx, uint32_t addr) {