java.lang.Object
io.github.mahmoudimus.quic.congestion.Bbr
All Implemented Interfaces:
Controller

public final class Bbr extends Object implements Controller
A BBR congestion controller, experimental as in quinn: it models the path's bottleneck bandwidth and minimum RTT instead of reacting to loss, aiming at less buffer bloat and better throughput on paths with a high bandwidth-delay product. quinn's port, which this follows, is based on a BBRv1 sender (bbr_sender.cc) and draft-cardwell-iccrg-bbr-congestion-control.

The controller moves through four modes: Bbr.Mode.STARTUP doubles the sending rate each round trip until the bandwidth estimate stops growing by 25% for three rounds (or a loss happens in that round), Bbr.Mode.DRAIN empties the queue built up doing so, and Bbr.Mode.PROBE_BW cycles its pacing gain through 1.25, 0.75 and six rounds of 1.0 around the estimate. When no PROBE_RTT has started for ten seconds, Bbr.Mode.PROBE_RTT cuts the window to three quarters of the bandwidth-delay product for at least 200 ms to measure the minimum RTT again. Losses put it in conservation, then growth, recovery until a round passes without any.

Where quinn's port departs from BBRv1, this one follows the draft: the bandwidth comes from the connection's delivery rate samples (onRateSample(long, io.github.mahmoudimus.quic.congestion.RateSample)) through a max filter that expires after ten round trips, the minimum RTT expires ten seconds after it was last measured or refreshed and only then starts a PROBE_RTT, and STARTUP grows the window only below its target. pacingRate() reaches the connection's pacer, which quinn's ignores, so DRAIN drains. The README of this module lists what still differs from the draft.

Rates are bytes per second; times are nanoseconds.

Threads. Not thread-safe; owned by one connection.

  • Constructor Details

    • Bbr

      public Bbr(BbrConfig config, long now, int currentMtu)
      A controller in STARTUP.
      Parameters:
      config - the configuration
      now - the current time
      currentMtu - the path's maximum UDP payload size
    • Bbr

      public Bbr(BbrConfig config, long now, int currentMtu, RandomGenerator.SplittableGenerator random)
      A controller in STARTUP with a chosen source of randomness, for reproducible runs.
      Parameters:
      config - the configuration
      now - the current time
      currentMtu - the path's maximum UDP payload size
      random - picks where in the PROBE_BW gain cycle each PROBE_BW starts
  • Method Details

    • onSent

      public void onSent(long now, long bytes, long lastPacketNumber)
      Description copied from interface: Controller
      One or more packets were just sent.
      Specified by:
      onSent in interface Controller
      Parameters:
      now - the current time
      bytes - the bytes sent
      lastPacketNumber - the number of the last packet sent
    • onAck

      public void onAck(long now, long sent, long bytes, boolean appLimited, RttEstimator rtt)
      Description copied from interface: Controller
      A packet's delivery was confirmed.
      Specified by:
      onAck in interface Controller
      Parameters:
      now - the current time
      sent - when the packet was sent
      bytes - the packet's size
      appLimited - whether the connection was limited by the application, not the window, before these acknowledgements
      rtt - the path's RTT estimate
    • onRateSample

      public void onRateSample(long now, RateSample sample)
      Description copied from interface: Controller
      The delivery rate sample of a batch of acknowledgements, given after their Controller.onAck(long, long, long, boolean, io.github.mahmoudimus.quic.congestion.RttEstimator) calls and before Controller.onEndAcks(long, long, boolean, long), when the batch acknowledged packets in flight. quinn has no such call.
      Specified by:
      onRateSample in interface Controller
      Parameters:
      now - the current time
      sample - the sample
    • onEndAcks

      public void onEndAcks(long now, long inFlight, boolean appLimited, long largestPacketNumberAcked)
      Description copied from interface: Controller
      A batch of acknowledgements, all with the same now, is complete.
      Specified by:
      onEndAcks in interface Controller
      Parameters:
      now - the current time
      inFlight - the bytes still in flight
      appLimited - whether the connection was application limited
      largestPacketNumberAcked - the largest packet number ever acknowledged in the space, or -1
    • onCongestionEvent

      public void onCongestionEvent(long now, long sent, boolean persistentCongestion, boolean ecn, long lostBytes)
      Description copied from interface: Controller
      Packets were deemed lost, or marked with ECN congestion experienced.
      Specified by:
      onCongestionEvent in interface Controller
      Parameters:
      now - the current time
      sent - when the most recent lost packet was sent
      persistentCongestion - whether every packet in the persistent congestion period ending with that packet was lost (RFC 9002 section 7.6)
      ecn - whether this is an ECN signal rather than loss
      lostBytes - the bytes lost, zero for ECN
    • onMtuUpdate

      public void onMtuUpdate(int newMtu)
      Description copied from interface: Controller
      The path's MTU changed.
      Specified by:
      onMtuUpdate in interface Controller
      Parameters:
      newMtu - the new maximum UDP payload size
    • window

      public long window()
      Description copied from interface: Controller
      The congestion window.
      Specified by:
      window in interface Controller
      Returns:
      the ack-eliciting bytes that may be in flight
    • metrics

      public ControllerMetrics metrics()
      Description copied from interface: Controller
      Metrics for statistics and tracing.
      Specified by:
      metrics in interface Controller
      Returns:
      the window and, where known, the slow start threshold
    • copy

      public Controller copy()
      Description copied from interface: Controller
      A copy of the controller's state, for a new path that starts from this one.
      Specified by:
      copy in interface Controller
      Returns:
      an independent copy
    • initialWindow

      public long initialWindow()
      Description copied from interface: Controller
      The initial window.
      Specified by:
      initialWindow in interface Controller
      Returns:
      bytes
    • mode

      public Bbr.Mode mode()
      The current mode.
      Returns:
      the mode
    • bandwidthEstimate

      public long bandwidthEstimate()
      The bottleneck bandwidth estimate: the largest delivery rate sampled, not application limited, over the last ten round trips.
      Returns:
      bytes per second, 0 before the first sample
    • pacingRate

      public long pacingRate()
      The pacing rate: the bandwidth estimate times the pacing gain, or in STARTUP never less than the initial window per minimum RTT.
      Specified by:
      pacingRate in interface Controller
      Returns:
      bytes per second, or -1 before the first bandwidth sample
    • minRtt

      public long minRtt()
      The minimum RTT the model uses.
      Returns:
      nanoseconds, 0 before the first measurement
    • isAtFullBandwidth

      public boolean isAtFullBandwidth()
      Whether STARTUP found the bottleneck bandwidth.
      Returns:
      true once the bandwidth estimate stopped growing
    • roundCount

      public long roundCount()
      The round trips counted so far.
      Returns:
      the round count