quic_cc behaviour (quic v1.3.0)

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.

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.

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_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.

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.