onPacketLost method
Called when packets are declared lost: their bytes leave flight (RFC 9002 section 7.3) and the window contracts, once per recovery epoch. When the data is re-sent it is booked again by onPacketSent, as the new packet it is. Persistent congestion is the socket's call (PacketManager.persistentCongestion, then onPersistentCongestion).
Implementation
void onPacketLost(int bytes, List<UDXPacket> lostPackets) {
_inflight -= bytes;
if (_inflight < 0) _inflight = 0;
// Don't reduce CWND if we are already in a recovery period.
if (_inRecovery) {
return;
}
_epochStart = clock.now(); // Start of a new recovery epoch
_inRecovery = true;
_recoveryEndPacketNumber = packetManager.lastSentPacketNumber;
// CUBIC's W_max calculation and window reduction
_wMax = _cwnd; // Store the window size at the point of congestion.
_ssthresh = (_wMax * betaCubic).round();
if (_ssthresh < minCwnd) {
_ssthresh = minCwnd;
}
// Pre-calculate K
final wMaxInMss = _wMax / maxDatagramSize;
final diff = wMaxInMss * (1 - betaCubic) / c;
_k = pow(diff, 1 / 3).toDouble();
final oldCwnd = _cwnd;
_cwnd = _ssthresh; // Reduce the window
_updatePacingRate();
if (connectionId != null) {
metricsObserver?.onCongestionWindowUpdate(connectionId!, oldCwnd, _cwnd, 'loss_detected');
}
}