Added support for acking packets using a received packets header

This commit is contained in:
Collin Smith 2020-06-23 21:04:26 -07:00
parent 185bd6a73d
commit 53ceea02a8
2 changed files with 39 additions and 6 deletions

View File

@ -47,6 +47,10 @@ public class Packet {
return (flags & TYPE_MASK) == FRAGMENTED;
}
public static boolean isAck(byte flags) {
return (flags & ACK) == ACK;
}
private static int getAckBitsFlags(int ackBits, int prefixByte) {
if ((ackBits & ACK_BYTE0_MASK) != ACK_BYTE0_MASK) prefixByte |= ACK_BYTE0;
if ((ackBits & ACK_BYTE1_MASK) != ACK_BYTE1_MASK) prefixByte |= ACK_BYTE1;

View File

@ -137,17 +137,46 @@ public class ReliablePacketController {
return;
}
final boolean isStale;
final int sequence = headerData.sequence;
if (!receivedPackets.testInsert(sequence)) {
synchronized (receivedPackets) {
isStale = !receivedPackets.testInsert(sequence);
}
final boolean isAck = Packet.isAck(flags);
if (!isStale && !isAck) {
if (DEBUG_RECEIVE) Log.debug(TAG, "processing packet %d", sequence);
ByteBuf slice = bb.readSlice(bb.readableBytes());
channel.onPacketProcessed(sequence, slice);
synchronized (receivedPackets) {
ReceivedPacketData receivedPacketData = receivedPackets.insert(sequence);
receivedPacketData.time = time;
receivedPacketData.packetSize = packetSize;
}
}
if (!isStale || isAck) {
final int ack = headerData.ack;
for (int i = 0, ackBits = headerData.ackBits; i < Integer.SIZE && ackBits != 0; i++, ackBits >>>= 1) {
if ((ackBits & 1) != 0) {
int ackSequence = (ack - i) & Packet.USHORT_MAX_VALUE;
SentPacketData sentPacketData = sentPackets.find(ackSequence);
if (sentPacketData != null && !sentPacketData.acked) {
if (DEBUG_RECEIVE) Log.debug(TAG, "acked packet %d", ackSequence);
ReliableEndpoint.stats.NUM_PACKETS_ACKED++;
sentPacketData.acked = true;
// ack packet callback
// TODO: rtt
}
}
}
}
if (isStale) {
Log.error(TAG, "ignoring stale packet %d", sequence);
ReliableEndpoint.stats.NUM_PACKETS_STALE++;
return;
}
if (DEBUG_RECEIVE) Log.debug(TAG, "processing packet %d", sequence);
ByteBuf slice = bb.readSlice(bb.readableBytes());
channel.onPacketProcessed(sequence, slice);
// TODO...
} finally {
if (headerData != null) headerData.free();
}