From 15a6e05d960f5941effc3000a3cfa7079c24efa7 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Oct 24 2021 08:11:34 +0000 Subject: udprecvqueue --- diff --git a/udprecvqueue.cpp b/udprecvqueue.cpp new file mode 100644 index 0000000..0300428 --- /dev/null +++ b/udprecvqueue.cpp @@ -0,0 +1,95 @@ + +#include + +#include "tunnel.h" +#include "connection.h" +#include "udprecvqueue.h" + + + +UdpRecvQueue::UdpRecvQueue(Connection &connection): + connection(connection), + nextConfirmSendTime(connection.tunnel.time + connection.tunnel.udpConfirmDuration), + confirmRequired(), + finalEntryAdded(), + entries(), + currentIndex(), + endIndex() + { } + + +UdpRecvQueue::~UdpRecvQueue() + { } + + +bool UdpRecvQueue::recvUdp(unsigned int index, const void *data, int size) { + confirmRequired = true; + + if (size < 0 || size > PACKET_SIZE) + return false; + if (cycleLess(index, currentIndex) || !cycleLess(index, currentIndex + PACKETS_COUNT)) + return false; + if (finalEntryAdded && !cycleLess(index, endIndex)) + return false; + Entry &e = entries[(current + (index - currentIndex))%PACKETS_COUNT]; + if (e.received) + return false; + + e.received = true; + e.size = size; + if (e.size) { + memcpy(e.data, data, e.size); + if (cycleLess(endIndex, index + 1)) endIndex = index + 1; + } else { + finalEntryAdded = true; + endIndex = index + 1; + } + + return true; +} + + +bool UdpRecvQueue::sendUdpConfirm() { + Time time = connection.tunnel.time; + if (!confirmRequired || timeLess(time, nextConfirmSendTime)) + return false; + + unsigned int count = endIndex - currentIndex; + unsigned int bytesCount = count ? (count - 1)/8 + 1 : 0; + + Packet packet; + packet.init(connection.id.id, currentIndex, CMD_CONFIRM, bytesCount); + for(int i = 0; i < count; ++i) + if (entries[(current + i)%PACKETS_COUNT].received) + packet.payload[i/8] |= (1 << (i%8)); + connection.tunnel.sendUdpPacket(packet); + + confirmRequired = false; + nextConfirmSendTime = time + connection.tunnel.udpConfirmDuration; + return true; +} + + +int UdpRecvQueue::sendTcp() { + int sent = 0; + while(cycleLess(currentIndex, endIndex)) { + Entry &e = entries[current]; + if (!e.received) + break; + + if (!e.size) { + connection.udpActive = false; + connection.tunnel.termQueue.insert(connection.id); + } else + if (!connection.tcpSendQueue.push(e.data, e.size)) { + break; + } + + ++sent; + memset(&e, 0, sizeof(e)); + current = (current + 1)%PACKETS_COUNT; + } + if (sent) confirmRequired = true; + return sent; +} + diff --git a/udprecvqueue.h b/udprecvqueue.h new file mode 100644 index 0000000..f244b8b --- /dev/null +++ b/udprecvqueue.h @@ -0,0 +1,42 @@ +#ifndef UDPRECVQUEUE_H +#define UDPRECVQUEUE_H + + +#include "common.h" + + + +class Connection; + + +class UdpRecvQueue { +public: + struct Entry { + bool received; + unsigned short size; + unsigned char data[PACKET_SIZE]; + }; + +public: + Connection &connection; +private: + Time nextConfirmSendTime; + bool confirmRequired; + bool finalEntryAdded; + + Entry entries[PACKETS_COUNT]; + int current; + unsigned int currentIndex; + unsigned int endIndex; + +public: + explicit UdpRecvQueue(Connection &connection); + ~UdpRecvQueue(); + + bool recvUdp(unsigned int index, const void *data, int size); + bool sendUdpConfirm(); + int sendTcp(); +}; + + +#endif