onPacketLost method

void onPacketLost(
  1. int bytes,
  2. List<UDXPacket> lostPackets
)

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');
  }
}