quic_cc behaviour (quic v1.9.1)

View Source

QUIC congestion control behavior and facade.

This module defines the behavior for pluggable congestion control algorithms and provides a facade that delegates to the selected implementation.

Available Algorithms

- newreno (default): RFC 9002 NewReno implementation - bbr: BBRv3 (future implementation)

Usage

   %% Create with default algorithm (NewReno)
   State = quic_cc:new(),
   State = quic_cc:new(#{initial_window => 65536}),
  
   %% Create with explicit algorithm
   State = quic_cc:new(newreno, #{}),
   State = quic_cc:new(bbr, #{}).

Summary

Functions

Get the algorithm name for this CC state.

Get the available congestion window.

Get bytes currently in flight.

Check if we can send more bytes.

Check if a control message can be sent.

Get the current congestion window.

Detect persistent congestion from lost packets.

Get the current ECN-CE counter.

Get pacing tokens for sending.

Check if in recovery phase.

Check if in slow start phase.

Get the current max datagram size.

Get minimum recovery duration setting.

Create a new congestion control state with default algorithm (NewReno).

Create a new congestion control state with options. Uses the algorithm specified in options, or NewReno by default.

Create a new congestion control state with explicit algorithm.

Handle a congestion event (packet loss detected).

Handle ECN-CE signal.

Record that a packet was sent.

Process acknowledged packets.

Process acknowledged packets with largest acked sent time.

Batched on_packet_sent for a run: one update for newreno, a fold for other algorithms.

Handle persistent congestion.

Check if pacing allows sending.

Calculate pacing delay.

Fused send check (cwnd + pacing) for the hot send path. See the behavior callback for the return shape.

Batched send_check: approve up to MaxK packets of Size in one pass. Native for newreno; other algorithms fold send_check/3 with identical results.

Get the slow start threshold.

Update congestion control state when MTU changes.

Update pacing rate based on smoothed RTT.

Types

cc_algorithm/0

-type cc_algorithm() :: newreno | bbr | cubic.

cc_opts/0

-type cc_opts() ::
          #{initial_window => pos_integer(),
            minimum_window => pos_integer(),
            min_recovery_duration => non_neg_integer(),
            max_datagram_size => pos_integer(),
            algorithm => cc_algorithm()}.

cc_state/0

-opaque cc_state()

Callbacks

available_cwnd/1

-callback available_cwnd(State :: term()) -> non_neg_integer().

bytes_in_flight/1

-callback bytes_in_flight(State :: term()) -> non_neg_integer().

can_send/2

-callback can_send(State :: term(), Size :: non_neg_integer()) -> boolean().

can_send_control/2

-callback can_send_control(State :: term(), Size :: non_neg_integer()) -> boolean().

cwnd/1

-callback cwnd(State :: term()) -> non_neg_integer().

detect_persistent_congestion/3

-callback detect_persistent_congestion(LostInfo :: [{non_neg_integer(), non_neg_integer()}],
                                       PTO :: non_neg_integer(),
                                       State :: term()) ->
                                          boolean().

ecn_ce_counter/1

-callback ecn_ce_counter(State :: term()) -> non_neg_integer().

get_pacing_tokens/2

-callback get_pacing_tokens(State :: term(), Size :: non_neg_integer()) ->
                               {non_neg_integer(), State :: term()}.

in_recovery/1

-callback in_recovery(State :: term()) -> boolean().

in_slow_start/1

-callback in_slow_start(State :: term()) -> boolean().

max_datagram_size/1

-callback max_datagram_size(State :: term()) -> pos_integer().

min_recovery_duration/1

-callback min_recovery_duration(State :: term()) -> non_neg_integer().

new/1

-callback new(Opts :: cc_opts()) -> State :: term().

on_congestion_event/2

-callback on_congestion_event(State :: term(), SentTime :: non_neg_integer()) -> State :: term().

on_ecn_ce/2

-callback on_ecn_ce(State :: term(), ECNCE :: non_neg_integer()) -> State :: term().

on_packet_sent/2

-callback on_packet_sent(State :: term(), Size :: non_neg_integer()) -> State :: term().

on_packets_acked/2

-callback on_packets_acked(State :: term(), AckedBytes :: non_neg_integer()) -> State :: term().

on_packets_acked/3

-callback on_packets_acked(State :: term(),
                           AckedBytes :: non_neg_integer(),
                           LargestAckedSentTime :: non_neg_integer()) ->
                              State :: term().

on_packets_lost/2

-callback on_packets_lost(State :: term(), LostBytes :: non_neg_integer()) -> State :: term().

on_persistent_congestion/1

-callback on_persistent_congestion(State :: term()) -> State :: term().

pacing_allows/2

-callback pacing_allows(State :: term(), Size :: non_neg_integer()) -> boolean().

pacing_delay/2

-callback pacing_delay(State :: term(), Size :: non_neg_integer()) -> non_neg_integer().

send_check/3

-callback send_check(State :: term(), Size :: non_neg_integer(), Urgency :: non_neg_integer()) ->
                        {ok, State :: term()} |
                        {blocked_cwnd, non_neg_integer()} |
                        {blocked_pacing, non_neg_integer()}.

ssthresh/1

-callback ssthresh(State :: term()) -> non_neg_integer() | infinity.

update_mtu/2

-callback update_mtu(State :: term(), NewMTU :: pos_integer()) -> State :: term().

update_pacing_rate/2

-callback update_pacing_rate(State :: term(), SmoothedRTT :: non_neg_integer()) -> State :: term().

Functions

algorithm(Cc_wrapper)

-spec algorithm(cc_state()) -> cc_algorithm().

Get the algorithm name for this CC state.

available_cwnd(Cc_wrapper)

-spec available_cwnd(cc_state()) -> non_neg_integer().

Get the available congestion window.

bytes_in_flight(Cc_wrapper)

-spec bytes_in_flight(cc_state()) -> non_neg_integer().

Get bytes currently in flight.

can_send(Cc_wrapper, Size)

-spec can_send(cc_state(), non_neg_integer()) -> boolean().

Check if we can send more bytes.

can_send_control(Cc_wrapper, Size)

-spec can_send_control(cc_state(), non_neg_integer()) -> boolean().

Check if a control message can be sent.

cwnd(Cc_wrapper)

-spec cwnd(cc_state()) -> non_neg_integer().

Get the current congestion window.

detect_persistent_congestion(LostInfo, PTO, Cc_wrapper)

-spec detect_persistent_congestion([{non_neg_integer(), non_neg_integer()}],
                                   non_neg_integer(),
                                   cc_state()) ->
                                      boolean().

Detect persistent congestion from lost packets.

ecn_ce_counter(Cc_wrapper)

-spec ecn_ce_counter(cc_state()) -> non_neg_integer().

Get the current ECN-CE counter.

get_pacing_tokens(Cc_wrapper, Size)

-spec get_pacing_tokens(cc_state(), non_neg_integer()) -> {non_neg_integer(), cc_state()}.

Get pacing tokens for sending.

in_recovery(Cc_wrapper)

-spec in_recovery(cc_state()) -> boolean().

Check if in recovery phase.

in_slow_start(Cc_wrapper)

-spec in_slow_start(cc_state()) -> boolean().

Check if in slow start phase.

max_datagram_size(Cc_wrapper)

-spec max_datagram_size(cc_state()) -> pos_integer().

Get the current max datagram size.

min_recovery_duration(Cc_wrapper)

-spec min_recovery_duration(cc_state()) -> non_neg_integer().

Get minimum recovery duration setting.

new()

-spec new() -> cc_state().

Create a new congestion control state with default algorithm (NewReno).

new(Opts)

-spec new(cc_opts()) -> cc_state().

Create a new congestion control state with options. Uses the algorithm specified in options, or NewReno by default.

Options: - algorithm: CC algorithm (newreno | bbr), default: newreno - max_datagram_size: Maximum datagram size (default: 1200) - initial_window: Override initial congestion window - minimum_window: Lower bound for cwnd after congestion events - min_recovery_duration: Minimum time in recovery before exit (ms)

new(Algorithm, Opts)

-spec new(cc_algorithm(), cc_opts()) -> cc_state().

Create a new congestion control state with explicit algorithm.

Algorithm: newreno | bbr Options: Same as new/1 (algorithm option is ignored)

on_congestion_event(Cc_wrapper, SentTime)

-spec on_congestion_event(cc_state(), non_neg_integer()) -> cc_state().

Handle a congestion event (packet loss detected).

on_ecn_ce(Cc_wrapper, ECNCE)

-spec on_ecn_ce(cc_state(), non_neg_integer()) -> cc_state().

Handle ECN-CE signal.

on_packet_sent(Cc_wrapper, Size)

-spec on_packet_sent(cc_state(), non_neg_integer()) -> cc_state().

Record that a packet was sent.

on_packets_acked(Cc_wrapper, AckedBytes)

-spec on_packets_acked(cc_state(), non_neg_integer()) -> cc_state().

Process acknowledged packets.

on_packets_acked(Cc_wrapper, AckedBytes, LargestAckedSentTime)

-spec on_packets_acked(cc_state(), non_neg_integer(), non_neg_integer()) -> cc_state().

Process acknowledged packets with largest acked sent time.

on_packets_lost(Cc_wrapper, LostBytes)

-spec on_packets_lost(cc_state(), non_neg_integer()) -> cc_state().

Process lost packets.

on_packets_sent(Cc_wrapper, Sizes)

-spec on_packets_sent(cc_state(), [non_neg_integer()]) -> cc_state().

Batched on_packet_sent for a run: one update for newreno, a fold for other algorithms.

on_persistent_congestion(Cc_wrapper)

-spec on_persistent_congestion(cc_state()) -> cc_state().

Handle persistent congestion.

pacing_allows(Cc_wrapper, Size)

-spec pacing_allows(cc_state(), non_neg_integer()) -> boolean().

Check if pacing allows sending.

pacing_delay(Cc_wrapper, Size)

-spec pacing_delay(cc_state(), non_neg_integer()) -> non_neg_integer().

Calculate pacing delay.

send_check(Cc_wrapper, Size, Urgency)

-spec send_check(cc_state(), non_neg_integer(), non_neg_integer()) ->
                    {ok, cc_state()} |
                    {blocked_cwnd, non_neg_integer()} |
                    {blocked_pacing, non_neg_integer()}.

Fused send check (cwnd + pacing) for the hot send path. See the behavior callback for the return shape.

send_check_run(Cc_wrapper, Size, MaxK, Urgency)

-spec send_check_run(cc_state(), non_neg_integer(), non_neg_integer(), non_neg_integer()) ->
                        {non_neg_integer(), cc_state()}.

Batched send_check: approve up to MaxK packets of Size in one pass. Native for newreno; other algorithms fold send_check/3 with identical results.

ssthresh(Cc_wrapper)

-spec ssthresh(cc_state()) -> non_neg_integer() | infinity.

Get the slow start threshold.

update_mtu(Cc_wrapper, NewMTU)

-spec update_mtu(cc_state(), pos_integer()) -> cc_state().

Update congestion control state when MTU changes.

update_pacing_rate(Cc_wrapper, SmoothedRTT)

-spec update_pacing_rate(cc_state(), non_neg_integer()) -> cc_state().

Update pacing rate based on smoothed RTT.