void BbrCongestionController::onPacketAcked()

in quic/congestion_control/Bbr.cpp [184:265]


void BbrCongestionController::onPacketAcked(
    const AckEvent& ack,
    uint64_t prevInflightBytes,
    bool hasLoss) {
  SCOPE_EXIT {
    if (conn_.qLogger) {
      conn_.qLogger->addCongestionMetricUpdate(
          conn_.lossState.inflightBytes,
          getCongestionWindow(),
          kCongestionPacketAck,
          bbrStateToString(state_),
          bbrRecoveryStateToString(recoveryState_));
    }
  };
  if (ack.implicit) {
    // This is an implicit ACK during the handshake, we can't trust very
    // much about it except the fact that it does ACK some bytes.
    updateCwnd(ack.ackedBytes, 0);
    return;
  }
  if (ack.rttSample && minRttSampler_) {
    bool updated =
        minRttSampler_->newRttSample(ack.rttSample.value(), ack.ackTime);
    if (updated) {
      appLimitedSinceProbeRtt_ = false;
    }
  }

  bool newRoundTrip =
      updateRoundTripCounter(ack.largestNewlyAckedPacketSentTime);
  bool lastAckedPacketAppLimited =
      ack.ackedPackets.empty() ? false : ack.largestNewlyAckedPacketAppLimited;
  if (bandwidthSampler_) {
    bandwidthSampler_->onPacketAcked(ack, roundTripCounter_);
  }
  if (inRecovery()) {
    CHECK(endOfRecovery_.has_value());
    if (newRoundTrip &&
        recoveryState_ != BbrCongestionController::RecoveryState::GROWTH) {
      recoveryState_ = BbrCongestionController::RecoveryState::GROWTH;
    }
    if (ack.largestNewlyAckedPacketSentTime > *endOfRecovery_) {
      recoveryState_ = BbrCongestionController::RecoveryState::NOT_RECOVERY;
    } else {
      updateRecoveryWindowWithAck(ack.ackedBytes);
    }
  }

  auto excessiveBytes = updateAckAggregation(ack);

  // handleAckInProbeBw() needs to happen before we check exiting Startup and
  // Drain and transitToProbeBw(). Otherwise, we may transitToProbeBw() first
  // then immediately invoke a handleAckInProbeBw() to also transit to next
  // ProbwBw pacing cycle.
  if (state_ == BbrState::ProbeBw) {
    handleAckInProbeBw(ack.ackTime, prevInflightBytes, hasLoss);
  }

  if (newRoundTrip && !lastAckedPacketAppLimited) {
    detectBottleneckBandwidth(lastAckedPacketAppLimited);
  }

  if (shouldExitStartup()) {
    transitToDrain();
  }

  if (shouldExitDrain()) {
    transitToProbeBw(ack.ackTime);
  }

  if (shouldProbeRtt(ack.ackTime)) {
    transitToProbeRtt();
  }
  exitingQuiescene_ = false;

  if (state_ == BbrState::ProbeRtt && minRttSampler_) {
    handleAckInProbeRtt(newRoundTrip, ack.ackTime);
  }

  updateCwnd(ack.ackedBytes, excessiveBytes);
  updatePacing();
}