Blame udprecvqueue.cpp

15a6e0
15a6e0
#include <cstring></cstring>
15a6e0
15a6e0
#include "tunnel.h"
15a6e0
#include "connection.h"
15a6e0
#include "udprecvqueue.h"
15a6e0
15a6e0
15a6e0
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
	
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));
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) { 
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;
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