quic_pmtu (quic v1.3.1)

View Source

QUIC Path MTU Discovery implementation.

Implements Datagram Packetization Layer Path MTU Discovery (DPLPMTUD) to dynamically discover the optimal packet size for a path.

State Machine

The PMTU discovery follows RFC 8899 states:

  • disabled - PMTU discovery not active
  • base - Using base MTU (1200), ready to probe
  • searching - Binary search for optimal MTU in progress
  • search_complete - Found optimal MTU
  • error - Black hole detected, fell back to base MTU

Binary Search Algorithm

The module uses binary search between 1200 and max_mtu, stopping when the search range is less than 10 bytes.

Summary

Functions

Cancel all pending timers.

Create a probe packet (PING + PADDING frames).

Get the current effective MTU.

Get the current generation.

Get the current state.

Check if PMTU discovery is enabled.

Create a new PMTU state with default settings.

Create a new PMTU state with options.

Initialize PMTU probing after connection is established.

Reset black hole counter on successful ACK.

Track packet loss for black hole detection.

Reset PMTU state on path change (connection migration).

Record that a probe packet was sent.

Handle probe timeout.

Handle raise timer expiration for periodic re-probing.

Set the probe timeout timer.

Set the raise timer for periodic re-probing.

Check if we should send a probe packet.

Types

pmtu_opts/0

-type pmtu_opts() ::
          #{pmtu_enabled => boolean(),
            pmtu_max_mtu => pos_integer(),
            pmtu_probe_timeout => pos_integer(),
            pmtu_raise_interval => pos_integer()}.

Functions

cancel_timers(Pmtu_state)

-spec cancel_timers(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                                base_mtu :: pos_integer(),
                                current_mtu :: pos_integer(),
                                max_mtu :: pos_integer(),
                                search_min :: pos_integer(),
                                lost :: [pos_integer() | undefined],
                                last_probe_lost :: boolean(),
                                probe_size :: non_neg_integer(),
                                probe_pn :: non_neg_integer() | undefined,
                                generation :: non_neg_integer(),
                                probe_timer :: reference() | undefined,
                                raise_timer :: reference() | undefined,
                                black_hole_count :: non_neg_integer(),
                                black_hole_threshold :: pos_integer()}) ->
                       #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                   base_mtu :: pos_integer(),
                                   current_mtu :: pos_integer(),
                                   max_mtu :: pos_integer(),
                                   search_min :: pos_integer(),
                                   lost :: [pos_integer() | undefined],
                                   last_probe_lost :: boolean(),
                                   probe_size :: non_neg_integer(),
                                   probe_pn :: non_neg_integer() | undefined,
                                   generation :: non_neg_integer(),
                                   probe_timer :: reference() | undefined,
                                   raise_timer :: reference() | undefined,
                                   black_hole_count :: non_neg_integer(),
                                   black_hole_threshold :: pos_integer()}.

Cancel all pending timers.

create_probe_packet(Pmtu_state, HeaderSize)

-spec create_probe_packet(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                                      base_mtu :: pos_integer(),
                                      current_mtu :: pos_integer(),
                                      max_mtu :: pos_integer(),
                                      search_min :: pos_integer(),
                                      lost :: [pos_integer() | undefined],
                                      last_probe_lost :: boolean(),
                                      probe_size :: non_neg_integer(),
                                      probe_pn :: non_neg_integer() | undefined,
                                      generation :: non_neg_integer(),
                                      probe_timer :: reference() | undefined,
                                      raise_timer :: reference() | undefined,
                                      black_hole_count :: non_neg_integer(),
                                      black_hole_threshold :: pos_integer()},
                          pos_integer()) ->
                             {pos_integer(), [term()]}.

Create a probe packet (PING + PADDING frames).

Creates a packet with PING frame and PADDING to reach the target size. The probe size is calculated using binary search.

current_mtu(Pmtu_state)

-spec current_mtu(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                              base_mtu :: pos_integer(),
                              current_mtu :: pos_integer(),
                              max_mtu :: pos_integer(),
                              search_min :: pos_integer(),
                              lost :: [pos_integer() | undefined],
                              last_probe_lost :: boolean(),
                              probe_size :: non_neg_integer(),
                              probe_pn :: non_neg_integer() | undefined,
                              generation :: non_neg_integer(),
                              probe_timer :: reference() | undefined,
                              raise_timer :: reference() | undefined,
                              black_hole_count :: non_neg_integer(),
                              black_hole_threshold :: pos_integer()}) ->
                     pos_integer().

Get the current effective MTU.

get_generation(Pmtu_state)

-spec get_generation(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                                 base_mtu :: pos_integer(),
                                 current_mtu :: pos_integer(),
                                 max_mtu :: pos_integer(),
                                 search_min :: pos_integer(),
                                 lost :: [pos_integer() | undefined],
                                 last_probe_lost :: boolean(),
                                 probe_size :: non_neg_integer(),
                                 probe_pn :: non_neg_integer() | undefined,
                                 generation :: non_neg_integer(),
                                 probe_timer :: reference() | undefined,
                                 raise_timer :: reference() | undefined,
                                 black_hole_count :: non_neg_integer(),
                                 black_hole_threshold :: pos_integer()}) ->
                        non_neg_integer().

Get the current generation.

get_state(Pmtu_state)

-spec get_state(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                            base_mtu :: pos_integer(),
                            current_mtu :: pos_integer(),
                            max_mtu :: pos_integer(),
                            search_min :: pos_integer(),
                            lost :: [pos_integer() | undefined],
                            last_probe_lost :: boolean(),
                            probe_size :: non_neg_integer(),
                            probe_pn :: non_neg_integer() | undefined,
                            generation :: non_neg_integer(),
                            probe_timer :: reference() | undefined,
                            raise_timer :: reference() | undefined,
                            black_hole_count :: non_neg_integer(),
                            black_hole_threshold :: pos_integer()}) ->
                   disabled | base | searching | search_complete | error.

Get the current state.

is_enabled(Pmtu_state)

-spec is_enabled(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                             base_mtu :: pos_integer(),
                             current_mtu :: pos_integer(),
                             max_mtu :: pos_integer(),
                             search_min :: pos_integer(),
                             lost :: [pos_integer() | undefined],
                             last_probe_lost :: boolean(),
                             probe_size :: non_neg_integer(),
                             probe_pn :: non_neg_integer() | undefined,
                             generation :: non_neg_integer(),
                             probe_timer :: reference() | undefined,
                             raise_timer :: reference() | undefined,
                             black_hole_count :: non_neg_integer(),
                             black_hole_threshold :: pos_integer()}) ->
                    boolean().

Check if PMTU discovery is enabled.

new()

-spec new() ->
             #pmtu_state{state :: disabled | base | searching | search_complete | error,
                         base_mtu :: pos_integer(),
                         current_mtu :: pos_integer(),
                         max_mtu :: pos_integer(),
                         search_min :: pos_integer(),
                         lost :: [pos_integer() | undefined],
                         last_probe_lost :: boolean(),
                         probe_size :: non_neg_integer(),
                         probe_pn :: non_neg_integer() | undefined,
                         generation :: non_neg_integer(),
                         probe_timer :: reference() | undefined,
                         raise_timer :: reference() | undefined,
                         black_hole_count :: non_neg_integer(),
                         black_hole_threshold :: pos_integer()}.

Create a new PMTU state with default settings.

new(Opts)

-spec new(pmtu_opts()) ->
             #pmtu_state{state :: disabled | base | searching | search_complete | error,
                         base_mtu :: pos_integer(),
                         current_mtu :: pos_integer(),
                         max_mtu :: pos_integer(),
                         search_min :: pos_integer(),
                         lost :: [pos_integer() | undefined],
                         last_probe_lost :: boolean(),
                         probe_size :: non_neg_integer(),
                         probe_pn :: non_neg_integer() | undefined,
                         generation :: non_neg_integer(),
                         probe_timer :: reference() | undefined,
                         raise_timer :: reference() | undefined,
                         black_hole_count :: non_neg_integer(),
                         black_hole_threshold :: pos_integer()}.

Create a new PMTU state with options.

Options: - pmtu_enabled: Enable PMTU discovery (default: true) - pmtu_max_mtu: Maximum MTU to probe (default: 1500)

on_connection_established(PeerMax, Pmtu_state)

-spec on_connection_established(pos_integer() | undefined,
                                #pmtu_state{state ::
                                                disabled | base | searching | search_complete | error,
                                            base_mtu :: pos_integer(),
                                            current_mtu :: pos_integer(),
                                            max_mtu :: pos_integer(),
                                            search_min :: pos_integer(),
                                            lost :: [pos_integer() | undefined],
                                            last_probe_lost :: boolean(),
                                            probe_size :: non_neg_integer(),
                                            probe_pn :: non_neg_integer() | undefined,
                                            generation :: non_neg_integer(),
                                            probe_timer :: reference() | undefined,
                                            raise_timer :: reference() | undefined,
                                            black_hole_count :: non_neg_integer(),
                                            black_hole_threshold :: pos_integer()}) ->
                                   #pmtu_state{state ::
                                                   disabled | base | searching | search_complete | error,
                                               base_mtu :: pos_integer(),
                                               current_mtu :: pos_integer(),
                                               max_mtu :: pos_integer(),
                                               search_min :: pos_integer(),
                                               lost :: [pos_integer() | undefined],
                                               last_probe_lost :: boolean(),
                                               probe_size :: non_neg_integer(),
                                               probe_pn :: non_neg_integer() | undefined,
                                               generation :: non_neg_integer(),
                                               probe_timer :: reference() | undefined,
                                               raise_timer :: reference() | undefined,
                                               black_hole_count :: non_neg_integer(),
                                               black_hole_threshold :: pos_integer()}.

Initialize PMTU probing after connection is established.

Called when the QUIC handshake completes. Uses the peer's max_udp_payload_size transport parameter to set the upper bound.

on_packet_acked(Pmtu_state)

-spec on_packet_acked(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                                  base_mtu :: pos_integer(),
                                  current_mtu :: pos_integer(),
                                  max_mtu :: pos_integer(),
                                  search_min :: pos_integer(),
                                  lost :: [pos_integer() | undefined],
                                  last_probe_lost :: boolean(),
                                  probe_size :: non_neg_integer(),
                                  probe_pn :: non_neg_integer() | undefined,
                                  generation :: non_neg_integer(),
                                  probe_timer :: reference() | undefined,
                                  raise_timer :: reference() | undefined,
                                  black_hole_count :: non_neg_integer(),
                                  black_hole_threshold :: pos_integer()}) ->
                         #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                     base_mtu :: pos_integer(),
                                     current_mtu :: pos_integer(),
                                     max_mtu :: pos_integer(),
                                     search_min :: pos_integer(),
                                     lost :: [pos_integer() | undefined],
                                     last_probe_lost :: boolean(),
                                     probe_size :: non_neg_integer(),
                                     probe_pn :: non_neg_integer() | undefined,
                                     generation :: non_neg_integer(),
                                     probe_timer :: reference() | undefined,
                                     raise_timer :: reference() | undefined,
                                     black_hole_count :: non_neg_integer(),
                                     black_hole_threshold :: pos_integer()}.

Reset black hole counter on successful ACK.

on_packet_lost(PacketSize, Pmtu_state)

-spec on_packet_lost(pos_integer(),
                     #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                 base_mtu :: pos_integer(),
                                 current_mtu :: pos_integer(),
                                 max_mtu :: pos_integer(),
                                 search_min :: pos_integer(),
                                 lost :: [pos_integer() | undefined],
                                 last_probe_lost :: boolean(),
                                 probe_size :: non_neg_integer(),
                                 probe_pn :: non_neg_integer() | undefined,
                                 generation :: non_neg_integer(),
                                 probe_timer :: reference() | undefined,
                                 raise_timer :: reference() | undefined,
                                 black_hole_count :: non_neg_integer(),
                                 black_hole_threshold :: pos_integer()}) ->
                        #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                    base_mtu :: pos_integer(),
                                    current_mtu :: pos_integer(),
                                    max_mtu :: pos_integer(),
                                    search_min :: pos_integer(),
                                    lost :: [pos_integer() | undefined],
                                    last_probe_lost :: boolean(),
                                    probe_size :: non_neg_integer(),
                                    probe_pn :: non_neg_integer() | undefined,
                                    generation :: non_neg_integer(),
                                    probe_timer :: reference() | undefined,
                                    raise_timer :: reference() | undefined,
                                    black_hole_count :: non_neg_integer(),
                                    black_hole_threshold :: pos_integer()}.

Track packet loss for black hole detection.

Only counts losses of packets near the current MTU size (within 100 bytes). Small packet losses are not indicative of MTU black holes.

on_path_change(Pmtu_state)

-spec on_path_change(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                                 base_mtu :: pos_integer(),
                                 current_mtu :: pos_integer(),
                                 max_mtu :: pos_integer(),
                                 search_min :: pos_integer(),
                                 lost :: [pos_integer() | undefined],
                                 last_probe_lost :: boolean(),
                                 probe_size :: non_neg_integer(),
                                 probe_pn :: non_neg_integer() | undefined,
                                 generation :: non_neg_integer(),
                                 probe_timer :: reference() | undefined,
                                 raise_timer :: reference() | undefined,
                                 black_hole_count :: non_neg_integer(),
                                 black_hole_threshold :: pos_integer()}) ->
                        #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                    base_mtu :: pos_integer(),
                                    current_mtu :: pos_integer(),
                                    max_mtu :: pos_integer(),
                                    search_min :: pos_integer(),
                                    lost :: [pos_integer() | undefined],
                                    last_probe_lost :: boolean(),
                                    probe_size :: non_neg_integer(),
                                    probe_pn :: non_neg_integer() | undefined,
                                    generation :: non_neg_integer(),
                                    probe_timer :: reference() | undefined,
                                    raise_timer :: reference() | undefined,
                                    black_hole_count :: non_neg_integer(),
                                    black_hole_threshold :: pos_integer()}.

Reset PMTU state on path change (connection migration).

RFC 8899 Section 5.3.3: PMTU should be reset on path change since the new path may have different MTU characteristics.

on_probe_acked(PacketNumber, Gen, Pmtu_state)

-spec on_probe_acked(non_neg_integer(),
                     non_neg_integer(),
                     #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                 base_mtu :: pos_integer(),
                                 current_mtu :: pos_integer(),
                                 max_mtu :: pos_integer(),
                                 search_min :: pos_integer(),
                                 lost :: [pos_integer() | undefined],
                                 last_probe_lost :: boolean(),
                                 probe_size :: non_neg_integer(),
                                 probe_pn :: non_neg_integer() | undefined,
                                 generation :: non_neg_integer(),
                                 probe_timer :: reference() | undefined,
                                 raise_timer :: reference() | undefined,
                                 black_hole_count :: non_neg_integer(),
                                 black_hole_threshold :: pos_integer()}) ->
                        #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                    base_mtu :: pos_integer(),
                                    current_mtu :: pos_integer(),
                                    max_mtu :: pos_integer(),
                                    search_min :: pos_integer(),
                                    lost :: [pos_integer() | undefined],
                                    last_probe_lost :: boolean(),
                                    probe_size :: non_neg_integer(),
                                    probe_pn :: non_neg_integer() | undefined,
                                    generation :: non_neg_integer(),
                                    probe_timer :: reference() | undefined,
                                    raise_timer :: reference() | undefined,
                                    black_hole_count :: non_neg_integer(),
                                    black_hole_threshold :: pos_integer()}.

Handle probe packet ACK.

Called when the probe packet is acknowledged. On success, updates search bounds and MTU using the loss array algorithm.

on_probe_lost(PacketNumber, Gen, Pmtu_state)

-spec on_probe_lost(non_neg_integer(),
                    non_neg_integer(),
                    #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                base_mtu :: pos_integer(),
                                current_mtu :: pos_integer(),
                                max_mtu :: pos_integer(),
                                search_min :: pos_integer(),
                                lost :: [pos_integer() | undefined],
                                last_probe_lost :: boolean(),
                                probe_size :: non_neg_integer(),
                                probe_pn :: non_neg_integer() | undefined,
                                generation :: non_neg_integer(),
                                probe_timer :: reference() | undefined,
                                raise_timer :: reference() | undefined,
                                black_hole_count :: non_neg_integer(),
                                black_hole_threshold :: pos_integer()}) ->
                       #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                   base_mtu :: pos_integer(),
                                   current_mtu :: pos_integer(),
                                   max_mtu :: pos_integer(),
                                   search_min :: pos_integer(),
                                   lost :: [pos_integer() | undefined],
                                   last_probe_lost :: boolean(),
                                   probe_size :: non_neg_integer(),
                                   probe_pn :: non_neg_integer() | undefined,
                                   generation :: non_neg_integer(),
                                   probe_timer :: reference() | undefined,
                                   raise_timer :: reference() | undefined,
                                   black_hole_count :: non_neg_integer(),
                                   black_hole_threshold :: pos_integer()}.

Handle probe packet loss.

Called when the probe packet is detected as lost. Uses loss array algorithm: inserts loss into array and adjusts search.

on_probe_sent(PacketNumber, Pmtu_state)

-spec on_probe_sent(non_neg_integer(),
                    #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                base_mtu :: pos_integer(),
                                current_mtu :: pos_integer(),
                                max_mtu :: pos_integer(),
                                search_min :: pos_integer(),
                                lost :: [pos_integer() | undefined],
                                last_probe_lost :: boolean(),
                                probe_size :: non_neg_integer(),
                                probe_pn :: non_neg_integer() | undefined,
                                generation :: non_neg_integer(),
                                probe_timer :: reference() | undefined,
                                raise_timer :: reference() | undefined,
                                black_hole_count :: non_neg_integer(),
                                black_hole_threshold :: pos_integer()}) ->
                       {non_neg_integer(),
                        #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                    base_mtu :: pos_integer(),
                                    current_mtu :: pos_integer(),
                                    max_mtu :: pos_integer(),
                                    search_min :: pos_integer(),
                                    lost :: [pos_integer() | undefined],
                                    last_probe_lost :: boolean(),
                                    probe_size :: non_neg_integer(),
                                    probe_pn :: non_neg_integer() | undefined,
                                    generation :: non_neg_integer(),
                                    probe_timer :: reference() | undefined,
                                    raise_timer :: reference() | undefined,
                                    black_hole_count :: non_neg_integer(),
                                    black_hole_threshold :: pos_integer()}}.

Record that a probe packet was sent.

on_probe_timeout(Pmtu_state)

-spec on_probe_timeout(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                                   base_mtu :: pos_integer(),
                                   current_mtu :: pos_integer(),
                                   max_mtu :: pos_integer(),
                                   search_min :: pos_integer(),
                                   lost :: [pos_integer() | undefined],
                                   last_probe_lost :: boolean(),
                                   probe_size :: non_neg_integer(),
                                   probe_pn :: non_neg_integer() | undefined,
                                   generation :: non_neg_integer(),
                                   probe_timer :: reference() | undefined,
                                   raise_timer :: reference() | undefined,
                                   black_hole_count :: non_neg_integer(),
                                   black_hole_threshold :: pos_integer()}) ->
                          #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                      base_mtu :: pos_integer(),
                                      current_mtu :: pos_integer(),
                                      max_mtu :: pos_integer(),
                                      search_min :: pos_integer(),
                                      lost :: [pos_integer() | undefined],
                                      last_probe_lost :: boolean(),
                                      probe_size :: non_neg_integer(),
                                      probe_pn :: non_neg_integer() | undefined,
                                      generation :: non_neg_integer(),
                                      probe_timer :: reference() | undefined,
                                      raise_timer :: reference() | undefined,
                                      black_hole_count :: non_neg_integer(),
                                      black_hole_threshold :: pos_integer()}.

Handle probe timeout.

Called when the probe timer fires. Treats timeout as loss and uses loss array algorithm.

on_raise_timer(Pmtu_state)

-spec on_raise_timer(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                                 base_mtu :: pos_integer(),
                                 current_mtu :: pos_integer(),
                                 max_mtu :: pos_integer(),
                                 search_min :: pos_integer(),
                                 lost :: [pos_integer() | undefined],
                                 last_probe_lost :: boolean(),
                                 probe_size :: non_neg_integer(),
                                 probe_pn :: non_neg_integer() | undefined,
                                 generation :: non_neg_integer(),
                                 probe_timer :: reference() | undefined,
                                 raise_timer :: reference() | undefined,
                                 black_hole_count :: non_neg_integer(),
                                 black_hole_threshold :: pos_integer()}) ->
                        #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                    base_mtu :: pos_integer(),
                                    current_mtu :: pos_integer(),
                                    max_mtu :: pos_integer(),
                                    search_min :: pos_integer(),
                                    lost :: [pos_integer() | undefined],
                                    last_probe_lost :: boolean(),
                                    probe_size :: non_neg_integer(),
                                    probe_pn :: non_neg_integer() | undefined,
                                    generation :: non_neg_integer(),
                                    probe_timer :: reference() | undefined,
                                    raise_timer :: reference() | undefined,
                                    black_hole_count :: non_neg_integer(),
                                    black_hole_threshold :: pos_integer()}.

Handle raise timer expiration for periodic re-probing.

Unlike on_path_change, this keeps current_mtu and probes higher. Used for periodic attempts to increase MTU without dropping throughput.

set_probe_timer(TimerRef, Pmtu_state)

-spec set_probe_timer(reference(),
                      #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                  base_mtu :: pos_integer(),
                                  current_mtu :: pos_integer(),
                                  max_mtu :: pos_integer(),
                                  search_min :: pos_integer(),
                                  lost :: [pos_integer() | undefined],
                                  last_probe_lost :: boolean(),
                                  probe_size :: non_neg_integer(),
                                  probe_pn :: non_neg_integer() | undefined,
                                  generation :: non_neg_integer(),
                                  probe_timer :: reference() | undefined,
                                  raise_timer :: reference() | undefined,
                                  black_hole_count :: non_neg_integer(),
                                  black_hole_threshold :: pos_integer()}) ->
                         #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                     base_mtu :: pos_integer(),
                                     current_mtu :: pos_integer(),
                                     max_mtu :: pos_integer(),
                                     search_min :: pos_integer(),
                                     lost :: [pos_integer() | undefined],
                                     last_probe_lost :: boolean(),
                                     probe_size :: non_neg_integer(),
                                     probe_pn :: non_neg_integer() | undefined,
                                     generation :: non_neg_integer(),
                                     probe_timer :: reference() | undefined,
                                     raise_timer :: reference() | undefined,
                                     black_hole_count :: non_neg_integer(),
                                     black_hole_threshold :: pos_integer()}.

Set the probe timeout timer.

set_raise_timer(TimerRef, Pmtu_state)

-spec set_raise_timer(reference(),
                      #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                  base_mtu :: pos_integer(),
                                  current_mtu :: pos_integer(),
                                  max_mtu :: pos_integer(),
                                  search_min :: pos_integer(),
                                  lost :: [pos_integer() | undefined],
                                  last_probe_lost :: boolean(),
                                  probe_size :: non_neg_integer(),
                                  probe_pn :: non_neg_integer() | undefined,
                                  generation :: non_neg_integer(),
                                  probe_timer :: reference() | undefined,
                                  raise_timer :: reference() | undefined,
                                  black_hole_count :: non_neg_integer(),
                                  black_hole_threshold :: pos_integer()}) ->
                         #pmtu_state{state :: disabled | base | searching | search_complete | error,
                                     base_mtu :: pos_integer(),
                                     current_mtu :: pos_integer(),
                                     max_mtu :: pos_integer(),
                                     search_min :: pos_integer(),
                                     lost :: [pos_integer() | undefined],
                                     last_probe_lost :: boolean(),
                                     probe_size :: non_neg_integer(),
                                     probe_pn :: non_neg_integer() | undefined,
                                     generation :: non_neg_integer(),
                                     probe_timer :: reference() | undefined,
                                     raise_timer :: reference() | undefined,
                                     black_hole_count :: non_neg_integer(),
                                     black_hole_threshold :: pos_integer()}.

Set the raise timer for periodic re-probing.

should_probe(Pmtu_state)

-spec should_probe(#pmtu_state{state :: disabled | base | searching | search_complete | error,
                               base_mtu :: pos_integer(),
                               current_mtu :: pos_integer(),
                               max_mtu :: pos_integer(),
                               search_min :: pos_integer(),
                               lost :: [pos_integer() | undefined],
                               last_probe_lost :: boolean(),
                               probe_size :: non_neg_integer(),
                               probe_pn :: non_neg_integer() | undefined,
                               generation :: non_neg_integer(),
                               probe_timer :: reference() | undefined,
                               raise_timer :: reference() | undefined,
                               black_hole_count :: non_neg_integer(),
                               black_hole_threshold :: pos_integer()}) ->
                      boolean().

Check if we should send a probe packet.

Returns true if: - State is base (ready to start probing) - State is searching and no probe is in flight - State is error and raise timer expired