|
|
15a6e0 |
|
|
|
15a6e0 |
#include <cstring></cstring>
|
|
|
15a6e0 |
|
|
|
15a6e0 |
#include "tunnel.h"
|
|
|
15a6e0 |
#include "connection.h"
|
|
|
15a6e0 |
#include "udprecvqueue.h"
|
|
|
15a6e0 |
|
|
|
15a6e0 |
|
|
|
15a6e0 |
|
|
|
460064 |
//#define DebugMsg HideDebugMSG
|
|
|
460064 |
#define DebugMsg ShowDebugMSG
|
|
|
460064 |
|
|
|
460064 |
|
|
|
460064 |
|
|
|
15a6e0 |
UdpRecvQueue::UdpRecvQueue(Connection &connection):
|
|
|
15a6e0 |
connection(connection),
|
|
|
15a6e0 |
nextConfirmSendTime(connection.tunnel.time + connection.tunnel.udpConfirmDuration),
|
|
|
15a6e0 |
confirmRequired(),
|
|
|
15a6e0 |
finalEntryAdded(),
|
|
|
15a6e0 |
entries(),
|
|
|
15a6e0 |
currentIndex(),
|
|
|
15a6e0 |
endIndex()
|
|
|
15a6e0 |
{ }
|
|
|
15a6e0 |
|
|
|
15a6e0 |
|
|
|
15a6e0 |
UdpRecvQueue::~UdpRecvQueue()
|
|
|
15a6e0 |
{ }
|
|
|
15a6e0 |
|
|
|
15a6e0 |
|
|
|
15a6e0 |
bool UdpRecvQueue::recvUdp(unsigned int index, const void *data, int size) {
|
|
|
15a6e0 |
confirmRequired = true;
|
|
|
15a6e0 |
|
|
|
15a6e0 |
if (size < 0 || size > PACKET_SIZE)
|
|
|
15a6e0 |
return false;
|
|
|
15a6e0 |
if (cycleLess(index, currentIndex) || !cycleLess(index, currentIndex + PACKETS_COUNT))
|
|
|
15a6e0 |
return false;
|
|
|
15a6e0 |
if (finalEntryAdded && !cycleLess(index, endIndex))
|
|
|
15a6e0 |
return false;
|
|
|
15a6e0 |
Entry &e = entries[(current + (index - currentIndex))%PACKETS_COUNT];
|
|
|
15a6e0 |
if (e.received)
|
|
|
15a6e0 |
return false;
|
|
|
15a6e0 |
|
|
|
460064 |
DebugMsg("%u, %u, %d", connection.id.id, index, size);
|
|
|
15a6e0 |
e.received = true;
|
|
|
15a6e0 |
e.size = size;
|
|
|
15a6e0 |
if (e.size) {
|
|
|
15a6e0 |
memcpy(e.data, data, e.size);
|
|
|
15a6e0 |
if (cycleLess(endIndex, index + 1)) endIndex = index + 1;
|
|
|
15a6e0 |
} else {
|
|
|
15a6e0 |
finalEntryAdded = true;
|
|
|
15a6e0 |
endIndex = index + 1;
|
|
|
15a6e0 |
}
|
|
|
15a6e0 |
|
|
|
15a6e0 |
return true;
|
|
|
15a6e0 |
}
|
|
|
15a6e0 |
|
|
|
15a6e0 |
|
|
|
c47604 |
bool UdpRecvQueue::sendUdpConfirm(bool force) {
|
|
|
15a6e0 |
Time time = connection.tunnel.time;
|
|
|
c47604 |
if (!force && (!confirmRequired || timeLess(time, nextConfirmSendTime)))
|
|
|
15a6e0 |
return false;
|
|
|
15a6e0 |
|
|
|
15a6e0 |
unsigned int count = endIndex - currentIndex;
|
|
|
15a6e0 |
unsigned int bytesCount = count ? (count - 1)/8 + 1 : 0;
|
|
|
15a6e0 |
|
|
|
15a6e0 |
Packet packet;
|
|
|
15a6e0 |
packet.init(connection.id.id, currentIndex, CMD_CONFIRM, bytesCount);
|
|
|
c47604 |
for(int i = 0; i < (int)count; ++i)
|
|
|
15a6e0 |
if (entries[(current + i)%PACKETS_COUNT].received)
|
|
|
15a6e0 |
packet.payload[i/8] |= (1 << (i%8));
|
|
|
460064 |
DebugMsg("%u, %u, %s", connection.id.id, currentIndex, bitsToString(packet.payload, bytesCount));
|
|
|
c47604 |
connection.tunnel.sendUdpPacket(connection.id.address, packet);
|
|
|
15a6e0 |
|
|
|
15a6e0 |
confirmRequired = false;
|
|
|
15a6e0 |
nextConfirmSendTime = time + connection.tunnel.udpConfirmDuration;
|
|
|
15a6e0 |
return true;
|
|
|
15a6e0 |
}
|
|
|
15a6e0 |
|
|
|
15a6e0 |
|
|
|
c47604 |
bool UdpRecvQueue::canSentToTcp() const
|
|
|
c47604 |
{ return cycleLess(currentIndex, endIndex) && entries[current].received && entries[current].size; }
|
|
|
c47604 |
|
|
|
c47604 |
|
|
|
15a6e0 |
int UdpRecvQueue::sendTcp() {
|
|
|
15a6e0 |
int sent = 0;
|
|
|
15a6e0 |
while(cycleLess(currentIndex, endIndex)) {
|
|
|
15a6e0 |
Entry &e = entries[current];
|
|
|
15a6e0 |
if (!e.received)
|
|
|
15a6e0 |
break;
|
|
|
15a6e0 |
|
|
|
15a6e0 |
if (!e.size) {
|
|
|
460064 |
DebugMsg("%d, inactivate udp, all packets received", connection.id.id);
|
|
|
15a6e0 |
connection.udpActive = false;
|
|
|
15a6e0 |
connection.tunnel.termQueue.insert(connection.id);
|
|
|
15a6e0 |
} else
|
|
|
15a6e0 |
if (!connection.tcpSendQueue.push(e.data, e.size)) {
|
|
|
15a6e0 |
break;
|
|
|
15a6e0 |
}
|
|
|
15a6e0 |
|
|
|
15a6e0 |
++sent;
|
|
|
15a6e0 |
memset(&e, 0, sizeof(e));
|
|
|
15a6e0 |
current = (current + 1)%PACKETS_COUNT;
|
|
|
460064 |
++currentIndex;
|
|
|
15a6e0 |
}
|
|
|
15a6e0 |
if (sent) confirmRequired = true;
|
|
|
15a6e0 |
return sent;
|
|
|
15a6e0 |
}
|
|
|
15a6e0 |
|
|
|
c47604 |
|
|
|
c47604 |
void UdpRecvQueue::whenWriteToUdp(Time &t) const {
|
|
|
c47604 |
if (confirmRequired && timeLess(nextConfirmSendTime, t))
|
|
|
c47604 |
t = nextConfirmSendTime;
|
|
|
c47604 |
}
|
|
|
c47604 |
|