handleAckFrame method
Processes an incoming AckFrame, marking packets as acknowledged.
Returns the packets the frame newly acknowledged, each under the sequence it was last sent with. The packets, not bare sequences: the caller needs their size and last send time, and the entries are removed here. The caller books them with the congestion controller and then runs detectLostPackets, in that order (RFC 9002 appendix A.7: the acknowledged bytes grow the window before the loss contracts it).
Implementation
List<UDXPacket> handleAckFrame(AckFrame frame) {
final newlyAcked = <UDXPacket>[];
void take(int seq) {
final packet = _sentPackets.remove(seq);
if (packet != null) {
packet.isAcked = true;
newlyAcked.add(packet);
}
}
// The first range ends at largestAcked, inclusive.
for (int i = 0; i < frame.firstAckRangeLength; i++) {
take(frame.largestAcked - i);
}
// Additional ranges, highest first. `gap` is counted from the packet just
// below the previous range; the next range's highest is `gap` below it.
int currentSeq = frame.largestAcked - frame.firstAckRangeLength;
for (final rangeBlock in frame.ackRanges) {
final rangeEnd = currentSeq - rangeBlock.gap;
for (int i = 0; i < rangeBlock.ackRangeLength; i++) {
take(rangeEnd - i);
}
currentSeq = rangeEnd - rangeBlock.ackRangeLength;
}
if (newlyAcked.isNotEmpty) {
_ackBeforeLoss = _lastAckTime;
_lastAckTime = clock.now();
if (frame.largestAcked > _largestAcked) _largestAcked = frame.largestAcked;
}
return newlyAcked;
}