nquic_conn_migration (nquic v1.0.0)

View Source

Connection-migration glue for the handshake state machine.

The pure migration core lives in nquic_protocol_migration; this module is the handshake-statem-side glue that opens/rebinds sockets, rotates connection IDs, queues PATH_CHALLENGE, and tears down listener dispatch routing. Functions take and return #conn_state{} (or a classified result) and never produce gen_statem transitions or action lists; nquic_conn_statem owns the FSM. flush_and_send/1 stays in the statem: callers here queue frames and the statem-side adapter flushes.

Summary

Functions

Rebind the client socket and queue a PATH_CHALLENGE for the new path. The challenge is left queued; the statem caller flushes.

Attempt the server_per_conn_fd self-migration, returning a classified result. Logging is the statem's responsibility; noop means the connection was not eligible.

Types

server_migration_result()

-type server_migration_result() ::
          #conn_state{role :: client | server,
                      scid :: nquic:connection_id(),
                      dcid :: nquic:connection_id(),
                      odcid :: nquic:connection_id() | undefined,
                      retry_scid :: nquic:connection_id() | undefined,
                      retry_token :: binary(),
                      version :: non_neg_integer(),
                      version_preference :: [non_neg_integer()],
                      socket :: nquic_socket:t() | undefined,
                      peer :: nquic_socket:sockaddr() | undefined,
                      select_info :: nquic_socket:select_info() | undefined,
                      pn_spaces :: #{nquic_packet:space() => map()},
                      app_next_pn :: non_neg_integer(),
                      app_largest_received :: integer(),
                      loss_state :: nquic_loss:loss_state() | undefined,
                      dispatch_table :: nquic_dispatch:t() | undefined,
                      listener :: pid() | undefined,
                      connect_waiters :: [gen_server:from()],
                      local_params ::
                          #transport_params{original_destination_connection_id ::
                                                nquic:connection_id() | undefined,
                                            max_idle_timeout :: non_neg_integer(),
                                            stateless_reset_token :: binary() | undefined,
                                            max_udp_payload_size :: pos_integer(),
                                            initial_max_data :: non_neg_integer(),
                                            initial_max_stream_data_bidi_local :: non_neg_integer(),
                                            initial_max_stream_data_bidi_remote :: non_neg_integer(),
                                            initial_max_stream_data_uni :: non_neg_integer(),
                                            initial_max_streams_bidi :: non_neg_integer(),
                                            initial_max_streams_uni :: non_neg_integer(),
                                            ack_delay_exponent :: 0..20,
                                            max_ack_delay :: non_neg_integer(),
                                            disable_active_migration :: boolean(),
                                            preferred_address ::
                                                nquic_transport:preferred_address() | undefined,
                                            active_connection_id_limit :: non_neg_integer(),
                                            initial_source_connection_id ::
                                                nquic:connection_id() | undefined,
                                            retry_source_connection_id ::
                                                nquic:connection_id() | undefined,
                                            version_information ::
                                                nquic_transport:version_information() | undefined,
                                            max_datagram_frame_size :: non_neg_integer() | undefined},
                      remote_params ::
                          #transport_params{original_destination_connection_id ::
                                                nquic:connection_id() | undefined,
                                            max_idle_timeout :: non_neg_integer(),
                                            stateless_reset_token :: binary() | undefined,
                                            max_udp_payload_size :: pos_integer(),
                                            initial_max_data :: non_neg_integer(),
                                            initial_max_stream_data_bidi_local :: non_neg_integer(),
                                            initial_max_stream_data_bidi_remote :: non_neg_integer(),
                                            initial_max_stream_data_uni :: non_neg_integer(),
                                            initial_max_streams_bidi :: non_neg_integer(),
                                            initial_max_streams_uni :: non_neg_integer(),
                                            ack_delay_exponent :: 0..20,
                                            max_ack_delay :: non_neg_integer(),
                                            disable_active_migration :: boolean(),
                                            preferred_address ::
                                                nquic_transport:preferred_address() | undefined,
                                            active_connection_id_limit :: non_neg_integer(),
                                            initial_source_connection_id ::
                                                nquic:connection_id() | undefined,
                                            retry_source_connection_id ::
                                                nquic:connection_id() | undefined,
                                            version_information ::
                                                nquic_transport:version_information() | undefined,
                                            max_datagram_frame_size :: non_neg_integer() | undefined} |
                          undefined,
                      server_packet_processed :: boolean(),
                      owner :: pid() | undefined,
                      owner_mon :: reference() | undefined,
                      deferred_flush_pending :: boolean(),
                      pending_ack_count :: non_neg_integer(),
                      last_idle_ms :: non_neg_integer() | infinity | undefined,
                      last_pto_ms :: non_neg_integer() | cancel | undefined,
                      recv_ecn :: nquic_socket:ecn_mark(),
                      pmtud :: nquic_pmtud:pmtud_state() | undefined,
                      gso_size :: undefined | pos_integer(),
                      max_payload_size :: pos_integer(),
                      server_per_conn_fd :: boolean(),
                      proactive_cids :: boolean(),
                      socket_connected :: boolean(),
                      self_migration_pending :: boolean(),
                      metrics_counters :: nquic_metrics:conn_counters() | undefined,
                      spin_enabled :: boolean(),
                      peer_spin :: 0..1,
                      new_token_enabled :: boolean(),
                      new_token_lifetime :: pos_integer(),
                      qlog :: undefined | nquic_qlog:qlog_state(),
                      close_kind :: undefined | local | peer | idle_timeout | protocol_error,
                      crypto ::
                          #conn_crypto{tls_state :: term(),
                                       keys :: #{nquic_packet:space() | rtt0 => map()},
                                       app_send_keys :: map() | undefined,
                                       app_recv_keys :: map() | undefined,
                                       crypto_buffer ::
                                           #{nquic_packet:space() =>
                                                 {non_neg_integer(), binary(), list()}},
                                       cipher :: aes_128_gcm | aes_256_gcm | chacha20_poly1305,
                                       cipher_suites ::
                                           [aes_128_gcm | aes_256_gcm | chacha20_poly1305] | undefined,
                                       key_phase :: boolean(),
                                       key_update_pending :: boolean(),
                                       client_app_secret :: binary() | undefined,
                                       server_app_secret :: binary() | undefined,
                                       old_read_keys :: #{key := binary(), iv := binary()} | undefined,
                                       zero_rtt_accepted :: boolean(),
                                       replay_protection :: module() | undefined,
                                       session_ticket :: map() | undefined,
                                       resumption_secret :: binary() | undefined,
                                       session_cache :: atom() | false | {module, module()} | undefined,
                                       token_cache :: atom() | false | {module, module()},
                                       alpn :: [binary()] | undefined,
                                       hostname :: string() | binary() | undefined,
                                       cert :: binary() | undefined,
                                       cert_chain :: [binary()],
                                       key :: any() | undefined,
                                       verify :: verify_none | verify_peer,
                                       cacerts :: [binary()],
                                       peer_cert :: binary() | undefined,
                                       static_key :: binary() | undefined},
                      streams_state ::
                          #conn_streams{streams ::
                                            #{nquic:stream_id() =>
                                                  #stream_state{stream_id :: nquic:stream_id(),
                                                                type :: bidi | uni,
                                                                send_state ::
                                                                    ready | send | data_sent |
                                                                    data_recvd | reset_sent |
                                                                    reset_recvd,
                                                                send_offset :: non_neg_integer(),
                                                                send_max_data :: non_neg_integer(),
                                                                last_stream_data_blocked ::
                                                                    non_neg_integer(),
                                                                pending_send_data :: [binary()],
                                                                pending_send_size :: non_neg_integer(),
                                                                pending_send_fin :: boolean(),
                                                                recv_state ::
                                                                    recv | size_known | data_recvd |
                                                                    reset_recvd | data_read | reset_read,
                                                                recv_offset :: non_neg_integer(),
                                                                recv_max_offset :: non_neg_integer(),
                                                                recv_window :: non_neg_integer(),
                                                                recv_buffer ::
                                                                    gb_trees:tree(non_neg_integer(),
                                                                                  {binary(), boolean()}),
                                                                app_buffer :: iodata(),
                                                                app_buffer_size :: non_neg_integer()}},
                                        next_bidi_stream :: nquic:stream_id() | undefined,
                                        next_uni_stream :: nquic:stream_id() | undefined,
                                        peer_max_streams_bidi :: non_neg_integer(),
                                        peer_max_streams_uni :: non_neg_integer(),
                                        local_max_streams_bidi :: non_neg_integer(),
                                        local_max_streams_uni :: non_neg_integer(),
                                        last_sent_max_streams_bidi :: non_neg_integer(),
                                        last_sent_max_streams_uni :: non_neg_integer(),
                                        max_peer_bidi_stream_id :: non_neg_integer() | undefined,
                                        max_peer_uni_stream_id :: non_neg_integer() | undefined,
                                        opened_peer_bidi_count :: non_neg_integer(),
                                        opened_peer_uni_count :: non_neg_integer(),
                                        closed_peer_bidi_wm :: integer(),
                                        closed_peer_uni_wm :: integer(),
                                        closed_peer_streams :: #{nquic:stream_id() => true},
                                        recv_waiters :: #{nquic:stream_id() => gen_statem:from()},
                                        accept_stream_waiters :: queue:queue(gen_statem:from()),
                                        pending_streams :: queue:queue(nquic:stream_id()),
                                        blocked_streams :: #{nquic:stream_id() => true},
                                        pending_send_streams :: #{nquic:stream_id() => true},
                                        send_buffer_high_water :: pos_integer(),
                                        send_timeout :: timeout(),
                                        send_waiters :: queue:queue(nquic_conn_send_waiters:t())},
                      flow ::
                          #conn_flow{local_max_data :: non_neg_integer(),
                                     remote_max_data :: non_neg_integer(),
                                     data_sent :: non_neg_integer(),
                                     data_received :: non_neg_integer(),
                                     last_data_blocked :: non_neg_integer(),
                                     pending_initial_frames :: [nquic_frame:t()],
                                     pending_handshake_frames :: [nquic_frame:t()],
                                     pending_app_frames :: [nquic_frame:t()],
                                     pending_app_pre_encoded ::
                                         [{non_neg_integer(), iodata(), nquic_frame:t()}],
                                     queued_app_send_bytes :: non_neg_integer()},
                      path ::
                          #conn_path_mgmt{path_state :: nquic_path:state() | undefined,
                                          peer_cids ::
                                              #{non_neg_integer() =>
                                                    #{cid := nquic:connection_id(), token := binary()}},
                                          local_cids :: #{non_neg_integer() => nquic:connection_id()},
                                          local_cid_seq :: non_neg_integer(),
                                          peer_retire_prior_to :: non_neg_integer(),
                                          anti_amp_bytes_received :: non_neg_integer(),
                                          anti_amp_bytes_sent :: non_neg_integer(),
                                          address_validated :: boolean()}}.

Functions

arm_recv_after_migration/1

-spec arm_recv_after_migration(#conn_state{role :: client | server,
                                           scid :: nquic:connection_id(),
                                           dcid :: nquic:connection_id(),
                                           odcid :: nquic:connection_id() | undefined,
                                           retry_scid :: nquic:connection_id() | undefined,
                                           retry_token :: binary(),
                                           version :: non_neg_integer(),
                                           version_preference :: [non_neg_integer()],
                                           socket :: nquic_socket:t() | undefined,
                                           peer :: nquic_socket:sockaddr() | undefined,
                                           select_info :: nquic_socket:select_info() | undefined,
                                           pn_spaces :: #{nquic_packet:space() => map()},
                                           app_next_pn :: non_neg_integer(),
                                           app_largest_received :: integer(),
                                           loss_state :: nquic_loss:loss_state() | undefined,
                                           dispatch_table :: nquic_dispatch:t() | undefined,
                                           listener :: pid() | undefined,
                                           connect_waiters :: [gen_server:from()],
                                           local_params ::
                                               #transport_params{original_destination_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 max_idle_timeout :: non_neg_integer(),
                                                                 stateless_reset_token ::
                                                                     binary() | undefined,
                                                                 max_udp_payload_size :: pos_integer(),
                                                                 initial_max_data :: non_neg_integer(),
                                                                 initial_max_stream_data_bidi_local ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_bidi_remote ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_uni ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 ack_delay_exponent :: 0..20,
                                                                 max_ack_delay :: non_neg_integer(),
                                                                 disable_active_migration :: boolean(),
                                                                 preferred_address ::
                                                                     nquic_transport:preferred_address() |
                                                                     undefined,
                                                                 active_connection_id_limit ::
                                                                     non_neg_integer(),
                                                                 initial_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 retry_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 version_information ::
                                                                     nquic_transport:version_information() |
                                                                     undefined,
                                                                 max_datagram_frame_size ::
                                                                     non_neg_integer() | undefined},
                                           remote_params ::
                                               #transport_params{original_destination_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 max_idle_timeout :: non_neg_integer(),
                                                                 stateless_reset_token ::
                                                                     binary() | undefined,
                                                                 max_udp_payload_size :: pos_integer(),
                                                                 initial_max_data :: non_neg_integer(),
                                                                 initial_max_stream_data_bidi_local ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_bidi_remote ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_uni ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 ack_delay_exponent :: 0..20,
                                                                 max_ack_delay :: non_neg_integer(),
                                                                 disable_active_migration :: boolean(),
                                                                 preferred_address ::
                                                                     nquic_transport:preferred_address() |
                                                                     undefined,
                                                                 active_connection_id_limit ::
                                                                     non_neg_integer(),
                                                                 initial_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 retry_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 version_information ::
                                                                     nquic_transport:version_information() |
                                                                     undefined,
                                                                 max_datagram_frame_size ::
                                                                     non_neg_integer() | undefined} |
                                               undefined,
                                           server_packet_processed :: boolean(),
                                           owner :: pid() | undefined,
                                           owner_mon :: reference() | undefined,
                                           deferred_flush_pending :: boolean(),
                                           pending_ack_count :: non_neg_integer(),
                                           last_idle_ms :: non_neg_integer() | infinity | undefined,
                                           last_pto_ms :: non_neg_integer() | cancel | undefined,
                                           recv_ecn :: nquic_socket:ecn_mark(),
                                           pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                           gso_size :: undefined | pos_integer(),
                                           max_payload_size :: pos_integer(),
                                           server_per_conn_fd :: boolean(),
                                           proactive_cids :: boolean(),
                                           socket_connected :: boolean(),
                                           self_migration_pending :: boolean(),
                                           metrics_counters :: nquic_metrics:conn_counters() | undefined,
                                           spin_enabled :: boolean(),
                                           peer_spin :: 0..1,
                                           new_token_enabled :: boolean(),
                                           new_token_lifetime :: pos_integer(),
                                           qlog :: undefined | nquic_qlog:qlog_state(),
                                           close_kind ::
                                               undefined | local | peer | idle_timeout | protocol_error,
                                           crypto ::
                                               #conn_crypto{tls_state :: term(),
                                                            keys ::
                                                                #{nquic_packet:space() | rtt0 => map()},
                                                            app_send_keys :: map() | undefined,
                                                            app_recv_keys :: map() | undefined,
                                                            crypto_buffer ::
                                                                #{nquic_packet:space() =>
                                                                      {non_neg_integer(),
                                                                       binary(),
                                                                       list()}},
                                                            cipher ::
                                                                aes_128_gcm | aes_256_gcm |
                                                                chacha20_poly1305,
                                                            cipher_suites ::
                                                                [aes_128_gcm | aes_256_gcm |
                                                                 chacha20_poly1305] |
                                                                undefined,
                                                            key_phase :: boolean(),
                                                            key_update_pending :: boolean(),
                                                            client_app_secret :: binary() | undefined,
                                                            server_app_secret :: binary() | undefined,
                                                            old_read_keys ::
                                                                #{key := binary(), iv := binary()} |
                                                                undefined,
                                                            zero_rtt_accepted :: boolean(),
                                                            replay_protection :: module() | undefined,
                                                            session_ticket :: map() | undefined,
                                                            resumption_secret :: binary() | undefined,
                                                            session_cache ::
                                                                atom() |
                                                                false |
                                                                {module, module()} |
                                                                undefined,
                                                            token_cache ::
                                                                atom() | false | {module, module()},
                                                            alpn :: [binary()] | undefined,
                                                            hostname :: string() | binary() | undefined,
                                                            cert :: binary() | undefined,
                                                            cert_chain :: [binary()],
                                                            key :: any() | undefined,
                                                            verify :: verify_none | verify_peer,
                                                            cacerts :: [binary()],
                                                            peer_cert :: binary() | undefined,
                                                            static_key :: binary() | undefined},
                                           streams_state ::
                                               #conn_streams{streams ::
                                                                 #{nquic:stream_id() =>
                                                                       #stream_state{stream_id ::
                                                                                         nquic:stream_id(),
                                                                                     type :: bidi | uni,
                                                                                     send_state ::
                                                                                         ready | send |
                                                                                         data_sent |
                                                                                         data_recvd |
                                                                                         reset_sent |
                                                                                         reset_recvd,
                                                                                     send_offset ::
                                                                                         non_neg_integer(),
                                                                                     send_max_data ::
                                                                                         non_neg_integer(),
                                                                                     last_stream_data_blocked ::
                                                                                         non_neg_integer(),
                                                                                     pending_send_data ::
                                                                                         [binary()],
                                                                                     pending_send_size ::
                                                                                         non_neg_integer(),
                                                                                     pending_send_fin ::
                                                                                         boolean(),
                                                                                     recv_state ::
                                                                                         recv |
                                                                                         size_known |
                                                                                         data_recvd |
                                                                                         reset_recvd |
                                                                                         data_read |
                                                                                         reset_read,
                                                                                     recv_offset ::
                                                                                         non_neg_integer(),
                                                                                     recv_max_offset ::
                                                                                         non_neg_integer(),
                                                                                     recv_window ::
                                                                                         non_neg_integer(),
                                                                                     recv_buffer ::
                                                                                         gb_trees:tree(non_neg_integer(),
                                                                                                       {binary(),
                                                                                                        boolean()}),
                                                                                     app_buffer ::
                                                                                         iodata(),
                                                                                     app_buffer_size ::
                                                                                         non_neg_integer()}},
                                                             next_bidi_stream ::
                                                                 nquic:stream_id() | undefined,
                                                             next_uni_stream ::
                                                                 nquic:stream_id() | undefined,
                                                             peer_max_streams_bidi :: non_neg_integer(),
                                                             peer_max_streams_uni :: non_neg_integer(),
                                                             local_max_streams_bidi :: non_neg_integer(),
                                                             local_max_streams_uni :: non_neg_integer(),
                                                             last_sent_max_streams_bidi ::
                                                                 non_neg_integer(),
                                                             last_sent_max_streams_uni ::
                                                                 non_neg_integer(),
                                                             max_peer_bidi_stream_id ::
                                                                 non_neg_integer() | undefined,
                                                             max_peer_uni_stream_id ::
                                                                 non_neg_integer() | undefined,
                                                             opened_peer_bidi_count :: non_neg_integer(),
                                                             opened_peer_uni_count :: non_neg_integer(),
                                                             closed_peer_bidi_wm :: integer(),
                                                             closed_peer_uni_wm :: integer(),
                                                             closed_peer_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             recv_waiters ::
                                                                 #{nquic:stream_id() =>
                                                                       gen_statem:from()},
                                                             accept_stream_waiters ::
                                                                 queue:queue(gen_statem:from()),
                                                             pending_streams ::
                                                                 queue:queue(nquic:stream_id()),
                                                             blocked_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             pending_send_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             send_buffer_high_water :: pos_integer(),
                                                             send_timeout :: timeout(),
                                                             send_waiters ::
                                                                 queue:queue(nquic_conn_send_waiters:t())},
                                           flow ::
                                               #conn_flow{local_max_data :: non_neg_integer(),
                                                          remote_max_data :: non_neg_integer(),
                                                          data_sent :: non_neg_integer(),
                                                          data_received :: non_neg_integer(),
                                                          last_data_blocked :: non_neg_integer(),
                                                          pending_initial_frames :: [nquic_frame:t()],
                                                          pending_handshake_frames :: [nquic_frame:t()],
                                                          pending_app_frames :: [nquic_frame:t()],
                                                          pending_app_pre_encoded ::
                                                              [{non_neg_integer(),
                                                                iodata(),
                                                                nquic_frame:t()}],
                                                          queued_app_send_bytes :: non_neg_integer()},
                                           path ::
                                               #conn_path_mgmt{path_state ::
                                                                   nquic_path:state() | undefined,
                                                               peer_cids ::
                                                                   #{non_neg_integer() =>
                                                                         #{cid := nquic:connection_id(),
                                                                           token := binary()}},
                                                               local_cids ::
                                                                   #{non_neg_integer() =>
                                                                         nquic:connection_id()},
                                                               local_cid_seq :: non_neg_integer(),
                                                               peer_retire_prior_to :: non_neg_integer(),
                                                               anti_amp_bytes_received ::
                                                                   non_neg_integer(),
                                                               anti_amp_bytes_sent :: non_neg_integer(),
                                                               address_validated :: boolean()}}) ->
                                  #conn_state{role :: client | server,
                                              scid :: nquic:connection_id(),
                                              dcid :: nquic:connection_id(),
                                              odcid :: nquic:connection_id() | undefined,
                                              retry_scid :: nquic:connection_id() | undefined,
                                              retry_token :: binary(),
                                              version :: non_neg_integer(),
                                              version_preference :: [non_neg_integer()],
                                              socket :: nquic_socket:t() | undefined,
                                              peer :: nquic_socket:sockaddr() | undefined,
                                              select_info :: nquic_socket:select_info() | undefined,
                                              pn_spaces :: #{nquic_packet:space() => map()},
                                              app_next_pn :: non_neg_integer(),
                                              app_largest_received :: integer(),
                                              loss_state :: nquic_loss:loss_state() | undefined,
                                              dispatch_table :: nquic_dispatch:t() | undefined,
                                              listener :: pid() | undefined,
                                              connect_waiters :: [gen_server:from()],
                                              local_params ::
                                                  #transport_params{original_destination_connection_id ::
                                                                        nquic:connection_id() |
                                                                        undefined,
                                                                    max_idle_timeout ::
                                                                        non_neg_integer(),
                                                                    stateless_reset_token ::
                                                                        binary() | undefined,
                                                                    max_udp_payload_size ::
                                                                        pos_integer(),
                                                                    initial_max_data ::
                                                                        non_neg_integer(),
                                                                    initial_max_stream_data_bidi_local ::
                                                                        non_neg_integer(),
                                                                    initial_max_stream_data_bidi_remote ::
                                                                        non_neg_integer(),
                                                                    initial_max_stream_data_uni ::
                                                                        non_neg_integer(),
                                                                    initial_max_streams_bidi ::
                                                                        non_neg_integer(),
                                                                    initial_max_streams_uni ::
                                                                        non_neg_integer(),
                                                                    ack_delay_exponent :: 0..20,
                                                                    max_ack_delay :: non_neg_integer(),
                                                                    disable_active_migration ::
                                                                        boolean(),
                                                                    preferred_address ::
                                                                        nquic_transport:preferred_address() |
                                                                        undefined,
                                                                    active_connection_id_limit ::
                                                                        non_neg_integer(),
                                                                    initial_source_connection_id ::
                                                                        nquic:connection_id() |
                                                                        undefined,
                                                                    retry_source_connection_id ::
                                                                        nquic:connection_id() |
                                                                        undefined,
                                                                    version_information ::
                                                                        nquic_transport:version_information() |
                                                                        undefined,
                                                                    max_datagram_frame_size ::
                                                                        non_neg_integer() | undefined},
                                              remote_params ::
                                                  #transport_params{original_destination_connection_id ::
                                                                        nquic:connection_id() |
                                                                        undefined,
                                                                    max_idle_timeout ::
                                                                        non_neg_integer(),
                                                                    stateless_reset_token ::
                                                                        binary() | undefined,
                                                                    max_udp_payload_size ::
                                                                        pos_integer(),
                                                                    initial_max_data ::
                                                                        non_neg_integer(),
                                                                    initial_max_stream_data_bidi_local ::
                                                                        non_neg_integer(),
                                                                    initial_max_stream_data_bidi_remote ::
                                                                        non_neg_integer(),
                                                                    initial_max_stream_data_uni ::
                                                                        non_neg_integer(),
                                                                    initial_max_streams_bidi ::
                                                                        non_neg_integer(),
                                                                    initial_max_streams_uni ::
                                                                        non_neg_integer(),
                                                                    ack_delay_exponent :: 0..20,
                                                                    max_ack_delay :: non_neg_integer(),
                                                                    disable_active_migration ::
                                                                        boolean(),
                                                                    preferred_address ::
                                                                        nquic_transport:preferred_address() |
                                                                        undefined,
                                                                    active_connection_id_limit ::
                                                                        non_neg_integer(),
                                                                    initial_source_connection_id ::
                                                                        nquic:connection_id() |
                                                                        undefined,
                                                                    retry_source_connection_id ::
                                                                        nquic:connection_id() |
                                                                        undefined,
                                                                    version_information ::
                                                                        nquic_transport:version_information() |
                                                                        undefined,
                                                                    max_datagram_frame_size ::
                                                                        non_neg_integer() | undefined} |
                                                  undefined,
                                              server_packet_processed :: boolean(),
                                              owner :: pid() | undefined,
                                              owner_mon :: reference() | undefined,
                                              deferred_flush_pending :: boolean(),
                                              pending_ack_count :: non_neg_integer(),
                                              last_idle_ms :: non_neg_integer() | infinity | undefined,
                                              last_pto_ms :: non_neg_integer() | cancel | undefined,
                                              recv_ecn :: nquic_socket:ecn_mark(),
                                              pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                              gso_size :: undefined | pos_integer(),
                                              max_payload_size :: pos_integer(),
                                              server_per_conn_fd :: boolean(),
                                              proactive_cids :: boolean(),
                                              socket_connected :: boolean(),
                                              self_migration_pending :: boolean(),
                                              metrics_counters ::
                                                  nquic_metrics:conn_counters() | undefined,
                                              spin_enabled :: boolean(),
                                              peer_spin :: 0..1,
                                              new_token_enabled :: boolean(),
                                              new_token_lifetime :: pos_integer(),
                                              qlog :: undefined | nquic_qlog:qlog_state(),
                                              close_kind ::
                                                  undefined | local | peer | idle_timeout |
                                                  protocol_error,
                                              crypto ::
                                                  #conn_crypto{tls_state :: term(),
                                                               keys ::
                                                                   #{nquic_packet:space() | rtt0 =>
                                                                         map()},
                                                               app_send_keys :: map() | undefined,
                                                               app_recv_keys :: map() | undefined,
                                                               crypto_buffer ::
                                                                   #{nquic_packet:space() =>
                                                                         {non_neg_integer(),
                                                                          binary(),
                                                                          list()}},
                                                               cipher ::
                                                                   aes_128_gcm | aes_256_gcm |
                                                                   chacha20_poly1305,
                                                               cipher_suites ::
                                                                   [aes_128_gcm | aes_256_gcm |
                                                                    chacha20_poly1305] |
                                                                   undefined,
                                                               key_phase :: boolean(),
                                                               key_update_pending :: boolean(),
                                                               client_app_secret :: binary() | undefined,
                                                               server_app_secret :: binary() | undefined,
                                                               old_read_keys ::
                                                                   #{key := binary(), iv := binary()} |
                                                                   undefined,
                                                               zero_rtt_accepted :: boolean(),
                                                               replay_protection :: module() | undefined,
                                                               session_ticket :: map() | undefined,
                                                               resumption_secret :: binary() | undefined,
                                                               session_cache ::
                                                                   atom() |
                                                                   false |
                                                                   {module, module()} |
                                                                   undefined,
                                                               token_cache ::
                                                                   atom() | false | {module, module()},
                                                               alpn :: [binary()] | undefined,
                                                               hostname ::
                                                                   string() | binary() | undefined,
                                                               cert :: binary() | undefined,
                                                               cert_chain :: [binary()],
                                                               key :: any() | undefined,
                                                               verify :: verify_none | verify_peer,
                                                               cacerts :: [binary()],
                                                               peer_cert :: binary() | undefined,
                                                               static_key :: binary() | undefined},
                                              streams_state ::
                                                  #conn_streams{streams ::
                                                                    #{nquic:stream_id() =>
                                                                          #stream_state{stream_id ::
                                                                                            nquic:stream_id(),
                                                                                        type ::
                                                                                            bidi | uni,
                                                                                        send_state ::
                                                                                            ready |
                                                                                            send |
                                                                                            data_sent |
                                                                                            data_recvd |
                                                                                            reset_sent |
                                                                                            reset_recvd,
                                                                                        send_offset ::
                                                                                            non_neg_integer(),
                                                                                        send_max_data ::
                                                                                            non_neg_integer(),
                                                                                        last_stream_data_blocked ::
                                                                                            non_neg_integer(),
                                                                                        pending_send_data ::
                                                                                            [binary()],
                                                                                        pending_send_size ::
                                                                                            non_neg_integer(),
                                                                                        pending_send_fin ::
                                                                                            boolean(),
                                                                                        recv_state ::
                                                                                            recv |
                                                                                            size_known |
                                                                                            data_recvd |
                                                                                            reset_recvd |
                                                                                            data_read |
                                                                                            reset_read,
                                                                                        recv_offset ::
                                                                                            non_neg_integer(),
                                                                                        recv_max_offset ::
                                                                                            non_neg_integer(),
                                                                                        recv_window ::
                                                                                            non_neg_integer(),
                                                                                        recv_buffer ::
                                                                                            gb_trees:tree(non_neg_integer(),
                                                                                                          {binary(),
                                                                                                           boolean()}),
                                                                                        app_buffer ::
                                                                                            iodata(),
                                                                                        app_buffer_size ::
                                                                                            non_neg_integer()}},
                                                                next_bidi_stream ::
                                                                    nquic:stream_id() | undefined,
                                                                next_uni_stream ::
                                                                    nquic:stream_id() | undefined,
                                                                peer_max_streams_bidi ::
                                                                    non_neg_integer(),
                                                                peer_max_streams_uni ::
                                                                    non_neg_integer(),
                                                                local_max_streams_bidi ::
                                                                    non_neg_integer(),
                                                                local_max_streams_uni ::
                                                                    non_neg_integer(),
                                                                last_sent_max_streams_bidi ::
                                                                    non_neg_integer(),
                                                                last_sent_max_streams_uni ::
                                                                    non_neg_integer(),
                                                                max_peer_bidi_stream_id ::
                                                                    non_neg_integer() | undefined,
                                                                max_peer_uni_stream_id ::
                                                                    non_neg_integer() | undefined,
                                                                opened_peer_bidi_count ::
                                                                    non_neg_integer(),
                                                                opened_peer_uni_count ::
                                                                    non_neg_integer(),
                                                                closed_peer_bidi_wm :: integer(),
                                                                closed_peer_uni_wm :: integer(),
                                                                closed_peer_streams ::
                                                                    #{nquic:stream_id() => true},
                                                                recv_waiters ::
                                                                    #{nquic:stream_id() =>
                                                                          gen_statem:from()},
                                                                accept_stream_waiters ::
                                                                    queue:queue(gen_statem:from()),
                                                                pending_streams ::
                                                                    queue:queue(nquic:stream_id()),
                                                                blocked_streams ::
                                                                    #{nquic:stream_id() => true},
                                                                pending_send_streams ::
                                                                    #{nquic:stream_id() => true},
                                                                send_buffer_high_water :: pos_integer(),
                                                                send_timeout :: timeout(),
                                                                send_waiters ::
                                                                    queue:queue(nquic_conn_send_waiters:t())},
                                              flow ::
                                                  #conn_flow{local_max_data :: non_neg_integer(),
                                                             remote_max_data :: non_neg_integer(),
                                                             data_sent :: non_neg_integer(),
                                                             data_received :: non_neg_integer(),
                                                             last_data_blocked :: non_neg_integer(),
                                                             pending_initial_frames :: [nquic_frame:t()],
                                                             pending_handshake_frames ::
                                                                 [nquic_frame:t()],
                                                             pending_app_frames :: [nquic_frame:t()],
                                                             pending_app_pre_encoded ::
                                                                 [{non_neg_integer(),
                                                                   iodata(),
                                                                   nquic_frame:t()}],
                                                             queued_app_send_bytes :: non_neg_integer()},
                                              path ::
                                                  #conn_path_mgmt{path_state ::
                                                                      nquic_path:state() | undefined,
                                                                  peer_cids ::
                                                                      #{non_neg_integer() =>
                                                                            #{cid :=
                                                                                  nquic:connection_id(),
                                                                              token := binary()}},
                                                                  local_cids ::
                                                                      #{non_neg_integer() =>
                                                                            nquic:connection_id()},
                                                                  local_cid_seq :: non_neg_integer(),
                                                                  peer_retire_prior_to ::
                                                                      non_neg_integer(),
                                                                  anti_amp_bytes_received ::
                                                                      non_neg_integer(),
                                                                  anti_amp_bytes_sent ::
                                                                      non_neg_integer(),
                                                                  address_validated :: boolean()}}.

attempt_server_migration/1

-spec attempt_server_migration(#conn_state{role :: client | server,
                                           scid :: nquic:connection_id(),
                                           dcid :: nquic:connection_id(),
                                           odcid :: nquic:connection_id() | undefined,
                                           retry_scid :: nquic:connection_id() | undefined,
                                           retry_token :: binary(),
                                           version :: non_neg_integer(),
                                           version_preference :: [non_neg_integer()],
                                           socket :: nquic_socket:t() | undefined,
                                           peer :: nquic_socket:sockaddr() | undefined,
                                           select_info :: nquic_socket:select_info() | undefined,
                                           pn_spaces :: #{nquic_packet:space() => map()},
                                           app_next_pn :: non_neg_integer(),
                                           app_largest_received :: integer(),
                                           loss_state :: nquic_loss:loss_state() | undefined,
                                           dispatch_table :: nquic_dispatch:t() | undefined,
                                           listener :: pid() | undefined,
                                           connect_waiters :: [gen_server:from()],
                                           local_params ::
                                               #transport_params{original_destination_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 max_idle_timeout :: non_neg_integer(),
                                                                 stateless_reset_token ::
                                                                     binary() | undefined,
                                                                 max_udp_payload_size :: pos_integer(),
                                                                 initial_max_data :: non_neg_integer(),
                                                                 initial_max_stream_data_bidi_local ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_bidi_remote ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_uni ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 ack_delay_exponent :: 0..20,
                                                                 max_ack_delay :: non_neg_integer(),
                                                                 disable_active_migration :: boolean(),
                                                                 preferred_address ::
                                                                     nquic_transport:preferred_address() |
                                                                     undefined,
                                                                 active_connection_id_limit ::
                                                                     non_neg_integer(),
                                                                 initial_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 retry_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 version_information ::
                                                                     nquic_transport:version_information() |
                                                                     undefined,
                                                                 max_datagram_frame_size ::
                                                                     non_neg_integer() | undefined},
                                           remote_params ::
                                               #transport_params{original_destination_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 max_idle_timeout :: non_neg_integer(),
                                                                 stateless_reset_token ::
                                                                     binary() | undefined,
                                                                 max_udp_payload_size :: pos_integer(),
                                                                 initial_max_data :: non_neg_integer(),
                                                                 initial_max_stream_data_bidi_local ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_bidi_remote ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_uni ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 ack_delay_exponent :: 0..20,
                                                                 max_ack_delay :: non_neg_integer(),
                                                                 disable_active_migration :: boolean(),
                                                                 preferred_address ::
                                                                     nquic_transport:preferred_address() |
                                                                     undefined,
                                                                 active_connection_id_limit ::
                                                                     non_neg_integer(),
                                                                 initial_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 retry_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 version_information ::
                                                                     nquic_transport:version_information() |
                                                                     undefined,
                                                                 max_datagram_frame_size ::
                                                                     non_neg_integer() | undefined} |
                                               undefined,
                                           server_packet_processed :: boolean(),
                                           owner :: pid() | undefined,
                                           owner_mon :: reference() | undefined,
                                           deferred_flush_pending :: boolean(),
                                           pending_ack_count :: non_neg_integer(),
                                           last_idle_ms :: non_neg_integer() | infinity | undefined,
                                           last_pto_ms :: non_neg_integer() | cancel | undefined,
                                           recv_ecn :: nquic_socket:ecn_mark(),
                                           pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                           gso_size :: undefined | pos_integer(),
                                           max_payload_size :: pos_integer(),
                                           server_per_conn_fd :: boolean(),
                                           proactive_cids :: boolean(),
                                           socket_connected :: boolean(),
                                           self_migration_pending :: boolean(),
                                           metrics_counters :: nquic_metrics:conn_counters() | undefined,
                                           spin_enabled :: boolean(),
                                           peer_spin :: 0..1,
                                           new_token_enabled :: boolean(),
                                           new_token_lifetime :: pos_integer(),
                                           qlog :: undefined | nquic_qlog:qlog_state(),
                                           close_kind ::
                                               undefined | local | peer | idle_timeout | protocol_error,
                                           crypto ::
                                               #conn_crypto{tls_state :: term(),
                                                            keys ::
                                                                #{nquic_packet:space() | rtt0 => map()},
                                                            app_send_keys :: map() | undefined,
                                                            app_recv_keys :: map() | undefined,
                                                            crypto_buffer ::
                                                                #{nquic_packet:space() =>
                                                                      {non_neg_integer(),
                                                                       binary(),
                                                                       list()}},
                                                            cipher ::
                                                                aes_128_gcm | aes_256_gcm |
                                                                chacha20_poly1305,
                                                            cipher_suites ::
                                                                [aes_128_gcm | aes_256_gcm |
                                                                 chacha20_poly1305] |
                                                                undefined,
                                                            key_phase :: boolean(),
                                                            key_update_pending :: boolean(),
                                                            client_app_secret :: binary() | undefined,
                                                            server_app_secret :: binary() | undefined,
                                                            old_read_keys ::
                                                                #{key := binary(), iv := binary()} |
                                                                undefined,
                                                            zero_rtt_accepted :: boolean(),
                                                            replay_protection :: module() | undefined,
                                                            session_ticket :: map() | undefined,
                                                            resumption_secret :: binary() | undefined,
                                                            session_cache ::
                                                                atom() |
                                                                false |
                                                                {module, module()} |
                                                                undefined,
                                                            token_cache ::
                                                                atom() | false | {module, module()},
                                                            alpn :: [binary()] | undefined,
                                                            hostname :: string() | binary() | undefined,
                                                            cert :: binary() | undefined,
                                                            cert_chain :: [binary()],
                                                            key :: any() | undefined,
                                                            verify :: verify_none | verify_peer,
                                                            cacerts :: [binary()],
                                                            peer_cert :: binary() | undefined,
                                                            static_key :: binary() | undefined},
                                           streams_state ::
                                               #conn_streams{streams ::
                                                                 #{nquic:stream_id() =>
                                                                       #stream_state{stream_id ::
                                                                                         nquic:stream_id(),
                                                                                     type :: bidi | uni,
                                                                                     send_state ::
                                                                                         ready | send |
                                                                                         data_sent |
                                                                                         data_recvd |
                                                                                         reset_sent |
                                                                                         reset_recvd,
                                                                                     send_offset ::
                                                                                         non_neg_integer(),
                                                                                     send_max_data ::
                                                                                         non_neg_integer(),
                                                                                     last_stream_data_blocked ::
                                                                                         non_neg_integer(),
                                                                                     pending_send_data ::
                                                                                         [binary()],
                                                                                     pending_send_size ::
                                                                                         non_neg_integer(),
                                                                                     pending_send_fin ::
                                                                                         boolean(),
                                                                                     recv_state ::
                                                                                         recv |
                                                                                         size_known |
                                                                                         data_recvd |
                                                                                         reset_recvd |
                                                                                         data_read |
                                                                                         reset_read,
                                                                                     recv_offset ::
                                                                                         non_neg_integer(),
                                                                                     recv_max_offset ::
                                                                                         non_neg_integer(),
                                                                                     recv_window ::
                                                                                         non_neg_integer(),
                                                                                     recv_buffer ::
                                                                                         gb_trees:tree(non_neg_integer(),
                                                                                                       {binary(),
                                                                                                        boolean()}),
                                                                                     app_buffer ::
                                                                                         iodata(),
                                                                                     app_buffer_size ::
                                                                                         non_neg_integer()}},
                                                             next_bidi_stream ::
                                                                 nquic:stream_id() | undefined,
                                                             next_uni_stream ::
                                                                 nquic:stream_id() | undefined,
                                                             peer_max_streams_bidi :: non_neg_integer(),
                                                             peer_max_streams_uni :: non_neg_integer(),
                                                             local_max_streams_bidi :: non_neg_integer(),
                                                             local_max_streams_uni :: non_neg_integer(),
                                                             last_sent_max_streams_bidi ::
                                                                 non_neg_integer(),
                                                             last_sent_max_streams_uni ::
                                                                 non_neg_integer(),
                                                             max_peer_bidi_stream_id ::
                                                                 non_neg_integer() | undefined,
                                                             max_peer_uni_stream_id ::
                                                                 non_neg_integer() | undefined,
                                                             opened_peer_bidi_count :: non_neg_integer(),
                                                             opened_peer_uni_count :: non_neg_integer(),
                                                             closed_peer_bidi_wm :: integer(),
                                                             closed_peer_uni_wm :: integer(),
                                                             closed_peer_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             recv_waiters ::
                                                                 #{nquic:stream_id() =>
                                                                       gen_statem:from()},
                                                             accept_stream_waiters ::
                                                                 queue:queue(gen_statem:from()),
                                                             pending_streams ::
                                                                 queue:queue(nquic:stream_id()),
                                                             blocked_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             pending_send_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             send_buffer_high_water :: pos_integer(),
                                                             send_timeout :: timeout(),
                                                             send_waiters ::
                                                                 queue:queue(nquic_conn_send_waiters:t())},
                                           flow ::
                                               #conn_flow{local_max_data :: non_neg_integer(),
                                                          remote_max_data :: non_neg_integer(),
                                                          data_sent :: non_neg_integer(),
                                                          data_received :: non_neg_integer(),
                                                          last_data_blocked :: non_neg_integer(),
                                                          pending_initial_frames :: [nquic_frame:t()],
                                                          pending_handshake_frames :: [nquic_frame:t()],
                                                          pending_app_frames :: [nquic_frame:t()],
                                                          pending_app_pre_encoded ::
                                                              [{non_neg_integer(),
                                                                iodata(),
                                                                nquic_frame:t()}],
                                                          queued_app_send_bytes :: non_neg_integer()},
                                           path ::
                                               #conn_path_mgmt{path_state ::
                                                                   nquic_path:state() | undefined,
                                                               peer_cids ::
                                                                   #{non_neg_integer() =>
                                                                         #{cid := nquic:connection_id(),
                                                                           token := binary()}},
                                                               local_cids ::
                                                                   #{non_neg_integer() =>
                                                                         nquic:connection_id()},
                                                               local_cid_seq :: non_neg_integer(),
                                                               peer_retire_prior_to :: non_neg_integer(),
                                                               anti_amp_bytes_received ::
                                                                   non_neg_integer(),
                                                               anti_amp_bytes_sent :: non_neg_integer(),
                                                               address_validated :: boolean()}}) ->
                                  {ok,
                                   #conn_state{role :: client | server,
                                               scid :: nquic:connection_id(),
                                               dcid :: nquic:connection_id(),
                                               odcid :: nquic:connection_id() | undefined,
                                               retry_scid :: nquic:connection_id() | undefined,
                                               retry_token :: binary(),
                                               version :: non_neg_integer(),
                                               version_preference :: [non_neg_integer()],
                                               socket :: nquic_socket:t() | undefined,
                                               peer :: nquic_socket:sockaddr() | undefined,
                                               select_info :: nquic_socket:select_info() | undefined,
                                               pn_spaces :: #{nquic_packet:space() => map()},
                                               app_next_pn :: non_neg_integer(),
                                               app_largest_received :: integer(),
                                               loss_state :: nquic_loss:loss_state() | undefined,
                                               dispatch_table :: nquic_dispatch:t() | undefined,
                                               listener :: pid() | undefined,
                                               connect_waiters :: [gen_server:from()],
                                               local_params ::
                                                   #transport_params{original_destination_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     max_idle_timeout ::
                                                                         non_neg_integer(),
                                                                     stateless_reset_token ::
                                                                         binary() | undefined,
                                                                     max_udp_payload_size ::
                                                                         pos_integer(),
                                                                     initial_max_data ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_bidi_local ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_bidi_remote ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_uni ::
                                                                         non_neg_integer(),
                                                                     initial_max_streams_bidi ::
                                                                         non_neg_integer(),
                                                                     initial_max_streams_uni ::
                                                                         non_neg_integer(),
                                                                     ack_delay_exponent :: 0..20,
                                                                     max_ack_delay :: non_neg_integer(),
                                                                     disable_active_migration ::
                                                                         boolean(),
                                                                     preferred_address ::
                                                                         nquic_transport:preferred_address() |
                                                                         undefined,
                                                                     active_connection_id_limit ::
                                                                         non_neg_integer(),
                                                                     initial_source_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     retry_source_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     version_information ::
                                                                         nquic_transport:version_information() |
                                                                         undefined,
                                                                     max_datagram_frame_size ::
                                                                         non_neg_integer() | undefined},
                                               remote_params ::
                                                   #transport_params{original_destination_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     max_idle_timeout ::
                                                                         non_neg_integer(),
                                                                     stateless_reset_token ::
                                                                         binary() | undefined,
                                                                     max_udp_payload_size ::
                                                                         pos_integer(),
                                                                     initial_max_data ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_bidi_local ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_bidi_remote ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_uni ::
                                                                         non_neg_integer(),
                                                                     initial_max_streams_bidi ::
                                                                         non_neg_integer(),
                                                                     initial_max_streams_uni ::
                                                                         non_neg_integer(),
                                                                     ack_delay_exponent :: 0..20,
                                                                     max_ack_delay :: non_neg_integer(),
                                                                     disable_active_migration ::
                                                                         boolean(),
                                                                     preferred_address ::
                                                                         nquic_transport:preferred_address() |
                                                                         undefined,
                                                                     active_connection_id_limit ::
                                                                         non_neg_integer(),
                                                                     initial_source_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     retry_source_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     version_information ::
                                                                         nquic_transport:version_information() |
                                                                         undefined,
                                                                     max_datagram_frame_size ::
                                                                         non_neg_integer() | undefined} |
                                                   undefined,
                                               server_packet_processed :: boolean(),
                                               owner :: pid() | undefined,
                                               owner_mon :: reference() | undefined,
                                               deferred_flush_pending :: boolean(),
                                               pending_ack_count :: non_neg_integer(),
                                               last_idle_ms :: non_neg_integer() | infinity | undefined,
                                               last_pto_ms :: non_neg_integer() | cancel | undefined,
                                               recv_ecn :: nquic_socket:ecn_mark(),
                                               pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                               gso_size :: undefined | pos_integer(),
                                               max_payload_size :: pos_integer(),
                                               server_per_conn_fd :: boolean(),
                                               proactive_cids :: boolean(),
                                               socket_connected :: boolean(),
                                               self_migration_pending :: boolean(),
                                               metrics_counters ::
                                                   nquic_metrics:conn_counters() | undefined,
                                               spin_enabled :: boolean(),
                                               peer_spin :: 0..1,
                                               new_token_enabled :: boolean(),
                                               new_token_lifetime :: pos_integer(),
                                               qlog :: undefined | nquic_qlog:qlog_state(),
                                               close_kind ::
                                                   undefined | local | peer | idle_timeout |
                                                   protocol_error,
                                               crypto ::
                                                   #conn_crypto{tls_state :: term(),
                                                                keys ::
                                                                    #{nquic_packet:space() | rtt0 =>
                                                                          map()},
                                                                app_send_keys :: map() | undefined,
                                                                app_recv_keys :: map() | undefined,
                                                                crypto_buffer ::
                                                                    #{nquic_packet:space() =>
                                                                          {non_neg_integer(),
                                                                           binary(),
                                                                           list()}},
                                                                cipher ::
                                                                    aes_128_gcm | aes_256_gcm |
                                                                    chacha20_poly1305,
                                                                cipher_suites ::
                                                                    [aes_128_gcm | aes_256_gcm |
                                                                     chacha20_poly1305] |
                                                                    undefined,
                                                                key_phase :: boolean(),
                                                                key_update_pending :: boolean(),
                                                                client_app_secret ::
                                                                    binary() | undefined,
                                                                server_app_secret ::
                                                                    binary() | undefined,
                                                                old_read_keys ::
                                                                    #{key := binary(), iv := binary()} |
                                                                    undefined,
                                                                zero_rtt_accepted :: boolean(),
                                                                replay_protection ::
                                                                    module() | undefined,
                                                                session_ticket :: map() | undefined,
                                                                resumption_secret ::
                                                                    binary() | undefined,
                                                                session_cache ::
                                                                    atom() |
                                                                    false |
                                                                    {module, module()} |
                                                                    undefined,
                                                                token_cache ::
                                                                    atom() | false | {module, module()},
                                                                alpn :: [binary()] | undefined,
                                                                hostname ::
                                                                    string() | binary() | undefined,
                                                                cert :: binary() | undefined,
                                                                cert_chain :: [binary()],
                                                                key :: any() | undefined,
                                                                verify :: verify_none | verify_peer,
                                                                cacerts :: [binary()],
                                                                peer_cert :: binary() | undefined,
                                                                static_key :: binary() | undefined},
                                               streams_state ::
                                                   #conn_streams{streams ::
                                                                     #{nquic:stream_id() =>
                                                                           #stream_state{stream_id ::
                                                                                             nquic:stream_id(),
                                                                                         type ::
                                                                                             bidi | uni,
                                                                                         send_state ::
                                                                                             ready |
                                                                                             send |
                                                                                             data_sent |
                                                                                             data_recvd |
                                                                                             reset_sent |
                                                                                             reset_recvd,
                                                                                         send_offset ::
                                                                                             non_neg_integer(),
                                                                                         send_max_data ::
                                                                                             non_neg_integer(),
                                                                                         last_stream_data_blocked ::
                                                                                             non_neg_integer(),
                                                                                         pending_send_data ::
                                                                                             [binary()],
                                                                                         pending_send_size ::
                                                                                             non_neg_integer(),
                                                                                         pending_send_fin ::
                                                                                             boolean(),
                                                                                         recv_state ::
                                                                                             recv |
                                                                                             size_known |
                                                                                             data_recvd |
                                                                                             reset_recvd |
                                                                                             data_read |
                                                                                             reset_read,
                                                                                         recv_offset ::
                                                                                             non_neg_integer(),
                                                                                         recv_max_offset ::
                                                                                             non_neg_integer(),
                                                                                         recv_window ::
                                                                                             non_neg_integer(),
                                                                                         recv_buffer ::
                                                                                             gb_trees:tree(non_neg_integer(),
                                                                                                           {binary(),
                                                                                                            boolean()}),
                                                                                         app_buffer ::
                                                                                             iodata(),
                                                                                         app_buffer_size ::
                                                                                             non_neg_integer()}},
                                                                 next_bidi_stream ::
                                                                     nquic:stream_id() | undefined,
                                                                 next_uni_stream ::
                                                                     nquic:stream_id() | undefined,
                                                                 peer_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 peer_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 local_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 local_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 last_sent_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 last_sent_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 max_peer_bidi_stream_id ::
                                                                     non_neg_integer() | undefined,
                                                                 max_peer_uni_stream_id ::
                                                                     non_neg_integer() | undefined,
                                                                 opened_peer_bidi_count ::
                                                                     non_neg_integer(),
                                                                 opened_peer_uni_count ::
                                                                     non_neg_integer(),
                                                                 closed_peer_bidi_wm :: integer(),
                                                                 closed_peer_uni_wm :: integer(),
                                                                 closed_peer_streams ::
                                                                     #{nquic:stream_id() => true},
                                                                 recv_waiters ::
                                                                     #{nquic:stream_id() =>
                                                                           gen_statem:from()},
                                                                 accept_stream_waiters ::
                                                                     queue:queue(gen_statem:from()),
                                                                 pending_streams ::
                                                                     queue:queue(nquic:stream_id()),
                                                                 blocked_streams ::
                                                                     #{nquic:stream_id() => true},
                                                                 pending_send_streams ::
                                                                     #{nquic:stream_id() => true},
                                                                 send_buffer_high_water :: pos_integer(),
                                                                 send_timeout :: timeout(),
                                                                 send_waiters ::
                                                                     queue:queue(nquic_conn_send_waiters:t())},
                                               flow ::
                                                   #conn_flow{local_max_data :: non_neg_integer(),
                                                              remote_max_data :: non_neg_integer(),
                                                              data_sent :: non_neg_integer(),
                                                              data_received :: non_neg_integer(),
                                                              last_data_blocked :: non_neg_integer(),
                                                              pending_initial_frames ::
                                                                  [nquic_frame:t()],
                                                              pending_handshake_frames ::
                                                                  [nquic_frame:t()],
                                                              pending_app_frames :: [nquic_frame:t()],
                                                              pending_app_pre_encoded ::
                                                                  [{non_neg_integer(),
                                                                    iodata(),
                                                                    nquic_frame:t()}],
                                                              queued_app_send_bytes :: non_neg_integer()},
                                               path ::
                                                   #conn_path_mgmt{path_state ::
                                                                       nquic_path:state() | undefined,
                                                                   peer_cids ::
                                                                       #{non_neg_integer() =>
                                                                             #{cid :=
                                                                                   nquic:connection_id(),
                                                                               token := binary()}},
                                                                   local_cids ::
                                                                       #{non_neg_integer() =>
                                                                             nquic:connection_id()},
                                                                   local_cid_seq :: non_neg_integer(),
                                                                   peer_retire_prior_to ::
                                                                       non_neg_integer(),
                                                                   anti_amp_bytes_received ::
                                                                       non_neg_integer(),
                                                                   anti_amp_bytes_sent ::
                                                                       non_neg_integer(),
                                                                   address_validated :: boolean()}}} |
                                  {error, term()}.

awaiting_per_conn_fd_cid/1

-spec awaiting_per_conn_fd_cid(#conn_state{role :: client | server,
                                           scid :: nquic:connection_id(),
                                           dcid :: nquic:connection_id(),
                                           odcid :: nquic:connection_id() | undefined,
                                           retry_scid :: nquic:connection_id() | undefined,
                                           retry_token :: binary(),
                                           version :: non_neg_integer(),
                                           version_preference :: [non_neg_integer()],
                                           socket :: nquic_socket:t() | undefined,
                                           peer :: nquic_socket:sockaddr() | undefined,
                                           select_info :: nquic_socket:select_info() | undefined,
                                           pn_spaces :: #{nquic_packet:space() => map()},
                                           app_next_pn :: non_neg_integer(),
                                           app_largest_received :: integer(),
                                           loss_state :: nquic_loss:loss_state() | undefined,
                                           dispatch_table :: nquic_dispatch:t() | undefined,
                                           listener :: pid() | undefined,
                                           connect_waiters :: [gen_server:from()],
                                           local_params ::
                                               #transport_params{original_destination_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 max_idle_timeout :: non_neg_integer(),
                                                                 stateless_reset_token ::
                                                                     binary() | undefined,
                                                                 max_udp_payload_size :: pos_integer(),
                                                                 initial_max_data :: non_neg_integer(),
                                                                 initial_max_stream_data_bidi_local ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_bidi_remote ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_uni ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 ack_delay_exponent :: 0..20,
                                                                 max_ack_delay :: non_neg_integer(),
                                                                 disable_active_migration :: boolean(),
                                                                 preferred_address ::
                                                                     nquic_transport:preferred_address() |
                                                                     undefined,
                                                                 active_connection_id_limit ::
                                                                     non_neg_integer(),
                                                                 initial_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 retry_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 version_information ::
                                                                     nquic_transport:version_information() |
                                                                     undefined,
                                                                 max_datagram_frame_size ::
                                                                     non_neg_integer() | undefined},
                                           remote_params ::
                                               #transport_params{original_destination_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 max_idle_timeout :: non_neg_integer(),
                                                                 stateless_reset_token ::
                                                                     binary() | undefined,
                                                                 max_udp_payload_size :: pos_integer(),
                                                                 initial_max_data :: non_neg_integer(),
                                                                 initial_max_stream_data_bidi_local ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_bidi_remote ::
                                                                     non_neg_integer(),
                                                                 initial_max_stream_data_uni ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 initial_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 ack_delay_exponent :: 0..20,
                                                                 max_ack_delay :: non_neg_integer(),
                                                                 disable_active_migration :: boolean(),
                                                                 preferred_address ::
                                                                     nquic_transport:preferred_address() |
                                                                     undefined,
                                                                 active_connection_id_limit ::
                                                                     non_neg_integer(),
                                                                 initial_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 retry_source_connection_id ::
                                                                     nquic:connection_id() | undefined,
                                                                 version_information ::
                                                                     nquic_transport:version_information() |
                                                                     undefined,
                                                                 max_datagram_frame_size ::
                                                                     non_neg_integer() | undefined} |
                                               undefined,
                                           server_packet_processed :: boolean(),
                                           owner :: pid() | undefined,
                                           owner_mon :: reference() | undefined,
                                           deferred_flush_pending :: boolean(),
                                           pending_ack_count :: non_neg_integer(),
                                           last_idle_ms :: non_neg_integer() | infinity | undefined,
                                           last_pto_ms :: non_neg_integer() | cancel | undefined,
                                           recv_ecn :: nquic_socket:ecn_mark(),
                                           pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                           gso_size :: undefined | pos_integer(),
                                           max_payload_size :: pos_integer(),
                                           server_per_conn_fd :: boolean(),
                                           proactive_cids :: boolean(),
                                           socket_connected :: boolean(),
                                           self_migration_pending :: boolean(),
                                           metrics_counters :: nquic_metrics:conn_counters() | undefined,
                                           spin_enabled :: boolean(),
                                           peer_spin :: 0..1,
                                           new_token_enabled :: boolean(),
                                           new_token_lifetime :: pos_integer(),
                                           qlog :: undefined | nquic_qlog:qlog_state(),
                                           close_kind ::
                                               undefined | local | peer | idle_timeout | protocol_error,
                                           crypto ::
                                               #conn_crypto{tls_state :: term(),
                                                            keys ::
                                                                #{nquic_packet:space() | rtt0 => map()},
                                                            app_send_keys :: map() | undefined,
                                                            app_recv_keys :: map() | undefined,
                                                            crypto_buffer ::
                                                                #{nquic_packet:space() =>
                                                                      {non_neg_integer(),
                                                                       binary(),
                                                                       list()}},
                                                            cipher ::
                                                                aes_128_gcm | aes_256_gcm |
                                                                chacha20_poly1305,
                                                            cipher_suites ::
                                                                [aes_128_gcm | aes_256_gcm |
                                                                 chacha20_poly1305] |
                                                                undefined,
                                                            key_phase :: boolean(),
                                                            key_update_pending :: boolean(),
                                                            client_app_secret :: binary() | undefined,
                                                            server_app_secret :: binary() | undefined,
                                                            old_read_keys ::
                                                                #{key := binary(), iv := binary()} |
                                                                undefined,
                                                            zero_rtt_accepted :: boolean(),
                                                            replay_protection :: module() | undefined,
                                                            session_ticket :: map() | undefined,
                                                            resumption_secret :: binary() | undefined,
                                                            session_cache ::
                                                                atom() |
                                                                false |
                                                                {module, module()} |
                                                                undefined,
                                                            token_cache ::
                                                                atom() | false | {module, module()},
                                                            alpn :: [binary()] | undefined,
                                                            hostname :: string() | binary() | undefined,
                                                            cert :: binary() | undefined,
                                                            cert_chain :: [binary()],
                                                            key :: any() | undefined,
                                                            verify :: verify_none | verify_peer,
                                                            cacerts :: [binary()],
                                                            peer_cert :: binary() | undefined,
                                                            static_key :: binary() | undefined},
                                           streams_state ::
                                               #conn_streams{streams ::
                                                                 #{nquic:stream_id() =>
                                                                       #stream_state{stream_id ::
                                                                                         nquic:stream_id(),
                                                                                     type :: bidi | uni,
                                                                                     send_state ::
                                                                                         ready | send |
                                                                                         data_sent |
                                                                                         data_recvd |
                                                                                         reset_sent |
                                                                                         reset_recvd,
                                                                                     send_offset ::
                                                                                         non_neg_integer(),
                                                                                     send_max_data ::
                                                                                         non_neg_integer(),
                                                                                     last_stream_data_blocked ::
                                                                                         non_neg_integer(),
                                                                                     pending_send_data ::
                                                                                         [binary()],
                                                                                     pending_send_size ::
                                                                                         non_neg_integer(),
                                                                                     pending_send_fin ::
                                                                                         boolean(),
                                                                                     recv_state ::
                                                                                         recv |
                                                                                         size_known |
                                                                                         data_recvd |
                                                                                         reset_recvd |
                                                                                         data_read |
                                                                                         reset_read,
                                                                                     recv_offset ::
                                                                                         non_neg_integer(),
                                                                                     recv_max_offset ::
                                                                                         non_neg_integer(),
                                                                                     recv_window ::
                                                                                         non_neg_integer(),
                                                                                     recv_buffer ::
                                                                                         gb_trees:tree(non_neg_integer(),
                                                                                                       {binary(),
                                                                                                        boolean()}),
                                                                                     app_buffer ::
                                                                                         iodata(),
                                                                                     app_buffer_size ::
                                                                                         non_neg_integer()}},
                                                             next_bidi_stream ::
                                                                 nquic:stream_id() | undefined,
                                                             next_uni_stream ::
                                                                 nquic:stream_id() | undefined,
                                                             peer_max_streams_bidi :: non_neg_integer(),
                                                             peer_max_streams_uni :: non_neg_integer(),
                                                             local_max_streams_bidi :: non_neg_integer(),
                                                             local_max_streams_uni :: non_neg_integer(),
                                                             last_sent_max_streams_bidi ::
                                                                 non_neg_integer(),
                                                             last_sent_max_streams_uni ::
                                                                 non_neg_integer(),
                                                             max_peer_bidi_stream_id ::
                                                                 non_neg_integer() | undefined,
                                                             max_peer_uni_stream_id ::
                                                                 non_neg_integer() | undefined,
                                                             opened_peer_bidi_count :: non_neg_integer(),
                                                             opened_peer_uni_count :: non_neg_integer(),
                                                             closed_peer_bidi_wm :: integer(),
                                                             closed_peer_uni_wm :: integer(),
                                                             closed_peer_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             recv_waiters ::
                                                                 #{nquic:stream_id() =>
                                                                       gen_statem:from()},
                                                             accept_stream_waiters ::
                                                                 queue:queue(gen_statem:from()),
                                                             pending_streams ::
                                                                 queue:queue(nquic:stream_id()),
                                                             blocked_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             pending_send_streams ::
                                                                 #{nquic:stream_id() => true},
                                                             send_buffer_high_water :: pos_integer(),
                                                             send_timeout :: timeout(),
                                                             send_waiters ::
                                                                 queue:queue(nquic_conn_send_waiters:t())},
                                           flow ::
                                               #conn_flow{local_max_data :: non_neg_integer(),
                                                          remote_max_data :: non_neg_integer(),
                                                          data_sent :: non_neg_integer(),
                                                          data_received :: non_neg_integer(),
                                                          last_data_blocked :: non_neg_integer(),
                                                          pending_initial_frames :: [nquic_frame:t()],
                                                          pending_handshake_frames :: [nquic_frame:t()],
                                                          pending_app_frames :: [nquic_frame:t()],
                                                          pending_app_pre_encoded ::
                                                              [{non_neg_integer(),
                                                                iodata(),
                                                                nquic_frame:t()}],
                                                          queued_app_send_bytes :: non_neg_integer()},
                                           path ::
                                               #conn_path_mgmt{path_state ::
                                                                   nquic_path:state() | undefined,
                                                               peer_cids ::
                                                                   #{non_neg_integer() =>
                                                                         #{cid := nquic:connection_id(),
                                                                           token := binary()}},
                                                               local_cids ::
                                                                   #{non_neg_integer() =>
                                                                         nquic:connection_id()},
                                                               local_cid_seq :: non_neg_integer(),
                                                               peer_retire_prior_to :: non_neg_integer(),
                                                               anti_amp_bytes_received ::
                                                                   non_neg_integer(),
                                                               anti_amp_bytes_sent :: non_neg_integer(),
                                                               address_validated :: boolean()}}) ->
                                  boolean().

finalize_server_migration/1

-spec finalize_server_migration(#conn_state{role :: client | server,
                                            scid :: nquic:connection_id(),
                                            dcid :: nquic:connection_id(),
                                            odcid :: nquic:connection_id() | undefined,
                                            retry_scid :: nquic:connection_id() | undefined,
                                            retry_token :: binary(),
                                            version :: non_neg_integer(),
                                            version_preference :: [non_neg_integer()],
                                            socket :: nquic_socket:t() | undefined,
                                            peer :: nquic_socket:sockaddr() | undefined,
                                            select_info :: nquic_socket:select_info() | undefined,
                                            pn_spaces :: #{nquic_packet:space() => map()},
                                            app_next_pn :: non_neg_integer(),
                                            app_largest_received :: integer(),
                                            loss_state :: nquic_loss:loss_state() | undefined,
                                            dispatch_table :: nquic_dispatch:t() | undefined,
                                            listener :: pid() | undefined,
                                            connect_waiters :: [gen_server:from()],
                                            local_params ::
                                                #transport_params{original_destination_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  max_idle_timeout :: non_neg_integer(),
                                                                  stateless_reset_token ::
                                                                      binary() | undefined,
                                                                  max_udp_payload_size :: pos_integer(),
                                                                  initial_max_data :: non_neg_integer(),
                                                                  initial_max_stream_data_bidi_local ::
                                                                      non_neg_integer(),
                                                                  initial_max_stream_data_bidi_remote ::
                                                                      non_neg_integer(),
                                                                  initial_max_stream_data_uni ::
                                                                      non_neg_integer(),
                                                                  initial_max_streams_bidi ::
                                                                      non_neg_integer(),
                                                                  initial_max_streams_uni ::
                                                                      non_neg_integer(),
                                                                  ack_delay_exponent :: 0..20,
                                                                  max_ack_delay :: non_neg_integer(),
                                                                  disable_active_migration :: boolean(),
                                                                  preferred_address ::
                                                                      nquic_transport:preferred_address() |
                                                                      undefined,
                                                                  active_connection_id_limit ::
                                                                      non_neg_integer(),
                                                                  initial_source_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  retry_source_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  version_information ::
                                                                      nquic_transport:version_information() |
                                                                      undefined,
                                                                  max_datagram_frame_size ::
                                                                      non_neg_integer() | undefined},
                                            remote_params ::
                                                #transport_params{original_destination_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  max_idle_timeout :: non_neg_integer(),
                                                                  stateless_reset_token ::
                                                                      binary() | undefined,
                                                                  max_udp_payload_size :: pos_integer(),
                                                                  initial_max_data :: non_neg_integer(),
                                                                  initial_max_stream_data_bidi_local ::
                                                                      non_neg_integer(),
                                                                  initial_max_stream_data_bidi_remote ::
                                                                      non_neg_integer(),
                                                                  initial_max_stream_data_uni ::
                                                                      non_neg_integer(),
                                                                  initial_max_streams_bidi ::
                                                                      non_neg_integer(),
                                                                  initial_max_streams_uni ::
                                                                      non_neg_integer(),
                                                                  ack_delay_exponent :: 0..20,
                                                                  max_ack_delay :: non_neg_integer(),
                                                                  disable_active_migration :: boolean(),
                                                                  preferred_address ::
                                                                      nquic_transport:preferred_address() |
                                                                      undefined,
                                                                  active_connection_id_limit ::
                                                                      non_neg_integer(),
                                                                  initial_source_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  retry_source_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  version_information ::
                                                                      nquic_transport:version_information() |
                                                                      undefined,
                                                                  max_datagram_frame_size ::
                                                                      non_neg_integer() | undefined} |
                                                undefined,
                                            server_packet_processed :: boolean(),
                                            owner :: pid() | undefined,
                                            owner_mon :: reference() | undefined,
                                            deferred_flush_pending :: boolean(),
                                            pending_ack_count :: non_neg_integer(),
                                            last_idle_ms :: non_neg_integer() | infinity | undefined,
                                            last_pto_ms :: non_neg_integer() | cancel | undefined,
                                            recv_ecn :: nquic_socket:ecn_mark(),
                                            pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                            gso_size :: undefined | pos_integer(),
                                            max_payload_size :: pos_integer(),
                                            server_per_conn_fd :: boolean(),
                                            proactive_cids :: boolean(),
                                            socket_connected :: boolean(),
                                            self_migration_pending :: boolean(),
                                            metrics_counters ::
                                                nquic_metrics:conn_counters() | undefined,
                                            spin_enabled :: boolean(),
                                            peer_spin :: 0..1,
                                            new_token_enabled :: boolean(),
                                            new_token_lifetime :: pos_integer(),
                                            qlog :: undefined | nquic_qlog:qlog_state(),
                                            close_kind ::
                                                undefined | local | peer | idle_timeout | protocol_error,
                                            crypto ::
                                                #conn_crypto{tls_state :: term(),
                                                             keys ::
                                                                 #{nquic_packet:space() | rtt0 => map()},
                                                             app_send_keys :: map() | undefined,
                                                             app_recv_keys :: map() | undefined,
                                                             crypto_buffer ::
                                                                 #{nquic_packet:space() =>
                                                                       {non_neg_integer(),
                                                                        binary(),
                                                                        list()}},
                                                             cipher ::
                                                                 aes_128_gcm | aes_256_gcm |
                                                                 chacha20_poly1305,
                                                             cipher_suites ::
                                                                 [aes_128_gcm | aes_256_gcm |
                                                                  chacha20_poly1305] |
                                                                 undefined,
                                                             key_phase :: boolean(),
                                                             key_update_pending :: boolean(),
                                                             client_app_secret :: binary() | undefined,
                                                             server_app_secret :: binary() | undefined,
                                                             old_read_keys ::
                                                                 #{key := binary(), iv := binary()} |
                                                                 undefined,
                                                             zero_rtt_accepted :: boolean(),
                                                             replay_protection :: module() | undefined,
                                                             session_ticket :: map() | undefined,
                                                             resumption_secret :: binary() | undefined,
                                                             session_cache ::
                                                                 atom() |
                                                                 false |
                                                                 {module, module()} |
                                                                 undefined,
                                                             token_cache ::
                                                                 atom() | false | {module, module()},
                                                             alpn :: [binary()] | undefined,
                                                             hostname :: string() | binary() | undefined,
                                                             cert :: binary() | undefined,
                                                             cert_chain :: [binary()],
                                                             key :: any() | undefined,
                                                             verify :: verify_none | verify_peer,
                                                             cacerts :: [binary()],
                                                             peer_cert :: binary() | undefined,
                                                             static_key :: binary() | undefined},
                                            streams_state ::
                                                #conn_streams{streams ::
                                                                  #{nquic:stream_id() =>
                                                                        #stream_state{stream_id ::
                                                                                          nquic:stream_id(),
                                                                                      type :: bidi | uni,
                                                                                      send_state ::
                                                                                          ready | send |
                                                                                          data_sent |
                                                                                          data_recvd |
                                                                                          reset_sent |
                                                                                          reset_recvd,
                                                                                      send_offset ::
                                                                                          non_neg_integer(),
                                                                                      send_max_data ::
                                                                                          non_neg_integer(),
                                                                                      last_stream_data_blocked ::
                                                                                          non_neg_integer(),
                                                                                      pending_send_data ::
                                                                                          [binary()],
                                                                                      pending_send_size ::
                                                                                          non_neg_integer(),
                                                                                      pending_send_fin ::
                                                                                          boolean(),
                                                                                      recv_state ::
                                                                                          recv |
                                                                                          size_known |
                                                                                          data_recvd |
                                                                                          reset_recvd |
                                                                                          data_read |
                                                                                          reset_read,
                                                                                      recv_offset ::
                                                                                          non_neg_integer(),
                                                                                      recv_max_offset ::
                                                                                          non_neg_integer(),
                                                                                      recv_window ::
                                                                                          non_neg_integer(),
                                                                                      recv_buffer ::
                                                                                          gb_trees:tree(non_neg_integer(),
                                                                                                        {binary(),
                                                                                                         boolean()}),
                                                                                      app_buffer ::
                                                                                          iodata(),
                                                                                      app_buffer_size ::
                                                                                          non_neg_integer()}},
                                                              next_bidi_stream ::
                                                                  nquic:stream_id() | undefined,
                                                              next_uni_stream ::
                                                                  nquic:stream_id() | undefined,
                                                              peer_max_streams_bidi :: non_neg_integer(),
                                                              peer_max_streams_uni :: non_neg_integer(),
                                                              local_max_streams_bidi ::
                                                                  non_neg_integer(),
                                                              local_max_streams_uni :: non_neg_integer(),
                                                              last_sent_max_streams_bidi ::
                                                                  non_neg_integer(),
                                                              last_sent_max_streams_uni ::
                                                                  non_neg_integer(),
                                                              max_peer_bidi_stream_id ::
                                                                  non_neg_integer() | undefined,
                                                              max_peer_uni_stream_id ::
                                                                  non_neg_integer() | undefined,
                                                              opened_peer_bidi_count ::
                                                                  non_neg_integer(),
                                                              opened_peer_uni_count :: non_neg_integer(),
                                                              closed_peer_bidi_wm :: integer(),
                                                              closed_peer_uni_wm :: integer(),
                                                              closed_peer_streams ::
                                                                  #{nquic:stream_id() => true},
                                                              recv_waiters ::
                                                                  #{nquic:stream_id() =>
                                                                        gen_statem:from()},
                                                              accept_stream_waiters ::
                                                                  queue:queue(gen_statem:from()),
                                                              pending_streams ::
                                                                  queue:queue(nquic:stream_id()),
                                                              blocked_streams ::
                                                                  #{nquic:stream_id() => true},
                                                              pending_send_streams ::
                                                                  #{nquic:stream_id() => true},
                                                              send_buffer_high_water :: pos_integer(),
                                                              send_timeout :: timeout(),
                                                              send_waiters ::
                                                                  queue:queue(nquic_conn_send_waiters:t())},
                                            flow ::
                                                #conn_flow{local_max_data :: non_neg_integer(),
                                                           remote_max_data :: non_neg_integer(),
                                                           data_sent :: non_neg_integer(),
                                                           data_received :: non_neg_integer(),
                                                           last_data_blocked :: non_neg_integer(),
                                                           pending_initial_frames :: [nquic_frame:t()],
                                                           pending_handshake_frames :: [nquic_frame:t()],
                                                           pending_app_frames :: [nquic_frame:t()],
                                                           pending_app_pre_encoded ::
                                                               [{non_neg_integer(),
                                                                 iodata(),
                                                                 nquic_frame:t()}],
                                                           queued_app_send_bytes :: non_neg_integer()},
                                            path ::
                                                #conn_path_mgmt{path_state ::
                                                                    nquic_path:state() | undefined,
                                                                peer_cids ::
                                                                    #{non_neg_integer() =>
                                                                          #{cid := nquic:connection_id(),
                                                                            token := binary()}},
                                                                local_cids ::
                                                                    #{non_neg_integer() =>
                                                                          nquic:connection_id()},
                                                                local_cid_seq :: non_neg_integer(),
                                                                peer_retire_prior_to ::
                                                                    non_neg_integer(),
                                                                anti_amp_bytes_received ::
                                                                    non_neg_integer(),
                                                                anti_amp_bytes_sent :: non_neg_integer(),
                                                                address_validated :: boolean()}}) ->
                                   #conn_state{role :: client | server,
                                               scid :: nquic:connection_id(),
                                               dcid :: nquic:connection_id(),
                                               odcid :: nquic:connection_id() | undefined,
                                               retry_scid :: nquic:connection_id() | undefined,
                                               retry_token :: binary(),
                                               version :: non_neg_integer(),
                                               version_preference :: [non_neg_integer()],
                                               socket :: nquic_socket:t() | undefined,
                                               peer :: nquic_socket:sockaddr() | undefined,
                                               select_info :: nquic_socket:select_info() | undefined,
                                               pn_spaces :: #{nquic_packet:space() => map()},
                                               app_next_pn :: non_neg_integer(),
                                               app_largest_received :: integer(),
                                               loss_state :: nquic_loss:loss_state() | undefined,
                                               dispatch_table :: nquic_dispatch:t() | undefined,
                                               listener :: pid() | undefined,
                                               connect_waiters :: [gen_server:from()],
                                               local_params ::
                                                   #transport_params{original_destination_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     max_idle_timeout ::
                                                                         non_neg_integer(),
                                                                     stateless_reset_token ::
                                                                         binary() | undefined,
                                                                     max_udp_payload_size ::
                                                                         pos_integer(),
                                                                     initial_max_data ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_bidi_local ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_bidi_remote ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_uni ::
                                                                         non_neg_integer(),
                                                                     initial_max_streams_bidi ::
                                                                         non_neg_integer(),
                                                                     initial_max_streams_uni ::
                                                                         non_neg_integer(),
                                                                     ack_delay_exponent :: 0..20,
                                                                     max_ack_delay :: non_neg_integer(),
                                                                     disable_active_migration ::
                                                                         boolean(),
                                                                     preferred_address ::
                                                                         nquic_transport:preferred_address() |
                                                                         undefined,
                                                                     active_connection_id_limit ::
                                                                         non_neg_integer(),
                                                                     initial_source_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     retry_source_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     version_information ::
                                                                         nquic_transport:version_information() |
                                                                         undefined,
                                                                     max_datagram_frame_size ::
                                                                         non_neg_integer() | undefined},
                                               remote_params ::
                                                   #transport_params{original_destination_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     max_idle_timeout ::
                                                                         non_neg_integer(),
                                                                     stateless_reset_token ::
                                                                         binary() | undefined,
                                                                     max_udp_payload_size ::
                                                                         pos_integer(),
                                                                     initial_max_data ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_bidi_local ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_bidi_remote ::
                                                                         non_neg_integer(),
                                                                     initial_max_stream_data_uni ::
                                                                         non_neg_integer(),
                                                                     initial_max_streams_bidi ::
                                                                         non_neg_integer(),
                                                                     initial_max_streams_uni ::
                                                                         non_neg_integer(),
                                                                     ack_delay_exponent :: 0..20,
                                                                     max_ack_delay :: non_neg_integer(),
                                                                     disable_active_migration ::
                                                                         boolean(),
                                                                     preferred_address ::
                                                                         nquic_transport:preferred_address() |
                                                                         undefined,
                                                                     active_connection_id_limit ::
                                                                         non_neg_integer(),
                                                                     initial_source_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     retry_source_connection_id ::
                                                                         nquic:connection_id() |
                                                                         undefined,
                                                                     version_information ::
                                                                         nquic_transport:version_information() |
                                                                         undefined,
                                                                     max_datagram_frame_size ::
                                                                         non_neg_integer() | undefined} |
                                                   undefined,
                                               server_packet_processed :: boolean(),
                                               owner :: pid() | undefined,
                                               owner_mon :: reference() | undefined,
                                               deferred_flush_pending :: boolean(),
                                               pending_ack_count :: non_neg_integer(),
                                               last_idle_ms :: non_neg_integer() | infinity | undefined,
                                               last_pto_ms :: non_neg_integer() | cancel | undefined,
                                               recv_ecn :: nquic_socket:ecn_mark(),
                                               pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                               gso_size :: undefined | pos_integer(),
                                               max_payload_size :: pos_integer(),
                                               server_per_conn_fd :: boolean(),
                                               proactive_cids :: boolean(),
                                               socket_connected :: boolean(),
                                               self_migration_pending :: boolean(),
                                               metrics_counters ::
                                                   nquic_metrics:conn_counters() | undefined,
                                               spin_enabled :: boolean(),
                                               peer_spin :: 0..1,
                                               new_token_enabled :: boolean(),
                                               new_token_lifetime :: pos_integer(),
                                               qlog :: undefined | nquic_qlog:qlog_state(),
                                               close_kind ::
                                                   undefined | local | peer | idle_timeout |
                                                   protocol_error,
                                               crypto ::
                                                   #conn_crypto{tls_state :: term(),
                                                                keys ::
                                                                    #{nquic_packet:space() | rtt0 =>
                                                                          map()},
                                                                app_send_keys :: map() | undefined,
                                                                app_recv_keys :: map() | undefined,
                                                                crypto_buffer ::
                                                                    #{nquic_packet:space() =>
                                                                          {non_neg_integer(),
                                                                           binary(),
                                                                           list()}},
                                                                cipher ::
                                                                    aes_128_gcm | aes_256_gcm |
                                                                    chacha20_poly1305,
                                                                cipher_suites ::
                                                                    [aes_128_gcm | aes_256_gcm |
                                                                     chacha20_poly1305] |
                                                                    undefined,
                                                                key_phase :: boolean(),
                                                                key_update_pending :: boolean(),
                                                                client_app_secret ::
                                                                    binary() | undefined,
                                                                server_app_secret ::
                                                                    binary() | undefined,
                                                                old_read_keys ::
                                                                    #{key := binary(), iv := binary()} |
                                                                    undefined,
                                                                zero_rtt_accepted :: boolean(),
                                                                replay_protection ::
                                                                    module() | undefined,
                                                                session_ticket :: map() | undefined,
                                                                resumption_secret ::
                                                                    binary() | undefined,
                                                                session_cache ::
                                                                    atom() |
                                                                    false |
                                                                    {module, module()} |
                                                                    undefined,
                                                                token_cache ::
                                                                    atom() | false | {module, module()},
                                                                alpn :: [binary()] | undefined,
                                                                hostname ::
                                                                    string() | binary() | undefined,
                                                                cert :: binary() | undefined,
                                                                cert_chain :: [binary()],
                                                                key :: any() | undefined,
                                                                verify :: verify_none | verify_peer,
                                                                cacerts :: [binary()],
                                                                peer_cert :: binary() | undefined,
                                                                static_key :: binary() | undefined},
                                               streams_state ::
                                                   #conn_streams{streams ::
                                                                     #{nquic:stream_id() =>
                                                                           #stream_state{stream_id ::
                                                                                             nquic:stream_id(),
                                                                                         type ::
                                                                                             bidi | uni,
                                                                                         send_state ::
                                                                                             ready |
                                                                                             send |
                                                                                             data_sent |
                                                                                             data_recvd |
                                                                                             reset_sent |
                                                                                             reset_recvd,
                                                                                         send_offset ::
                                                                                             non_neg_integer(),
                                                                                         send_max_data ::
                                                                                             non_neg_integer(),
                                                                                         last_stream_data_blocked ::
                                                                                             non_neg_integer(),
                                                                                         pending_send_data ::
                                                                                             [binary()],
                                                                                         pending_send_size ::
                                                                                             non_neg_integer(),
                                                                                         pending_send_fin ::
                                                                                             boolean(),
                                                                                         recv_state ::
                                                                                             recv |
                                                                                             size_known |
                                                                                             data_recvd |
                                                                                             reset_recvd |
                                                                                             data_read |
                                                                                             reset_read,
                                                                                         recv_offset ::
                                                                                             non_neg_integer(),
                                                                                         recv_max_offset ::
                                                                                             non_neg_integer(),
                                                                                         recv_window ::
                                                                                             non_neg_integer(),
                                                                                         recv_buffer ::
                                                                                             gb_trees:tree(non_neg_integer(),
                                                                                                           {binary(),
                                                                                                            boolean()}),
                                                                                         app_buffer ::
                                                                                             iodata(),
                                                                                         app_buffer_size ::
                                                                                             non_neg_integer()}},
                                                                 next_bidi_stream ::
                                                                     nquic:stream_id() | undefined,
                                                                 next_uni_stream ::
                                                                     nquic:stream_id() | undefined,
                                                                 peer_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 peer_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 local_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 local_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 last_sent_max_streams_bidi ::
                                                                     non_neg_integer(),
                                                                 last_sent_max_streams_uni ::
                                                                     non_neg_integer(),
                                                                 max_peer_bidi_stream_id ::
                                                                     non_neg_integer() | undefined,
                                                                 max_peer_uni_stream_id ::
                                                                     non_neg_integer() | undefined,
                                                                 opened_peer_bidi_count ::
                                                                     non_neg_integer(),
                                                                 opened_peer_uni_count ::
                                                                     non_neg_integer(),
                                                                 closed_peer_bidi_wm :: integer(),
                                                                 closed_peer_uni_wm :: integer(),
                                                                 closed_peer_streams ::
                                                                     #{nquic:stream_id() => true},
                                                                 recv_waiters ::
                                                                     #{nquic:stream_id() =>
                                                                           gen_statem:from()},
                                                                 accept_stream_waiters ::
                                                                     queue:queue(gen_statem:from()),
                                                                 pending_streams ::
                                                                     queue:queue(nquic:stream_id()),
                                                                 blocked_streams ::
                                                                     #{nquic:stream_id() => true},
                                                                 pending_send_streams ::
                                                                     #{nquic:stream_id() => true},
                                                                 send_buffer_high_water :: pos_integer(),
                                                                 send_timeout :: timeout(),
                                                                 send_waiters ::
                                                                     queue:queue(nquic_conn_send_waiters:t())},
                                               flow ::
                                                   #conn_flow{local_max_data :: non_neg_integer(),
                                                              remote_max_data :: non_neg_integer(),
                                                              data_sent :: non_neg_integer(),
                                                              data_received :: non_neg_integer(),
                                                              last_data_blocked :: non_neg_integer(),
                                                              pending_initial_frames ::
                                                                  [nquic_frame:t()],
                                                              pending_handshake_frames ::
                                                                  [nquic_frame:t()],
                                                              pending_app_frames :: [nquic_frame:t()],
                                                              pending_app_pre_encoded ::
                                                                  [{non_neg_integer(),
                                                                    iodata(),
                                                                    nquic_frame:t()}],
                                                              queued_app_send_bytes :: non_neg_integer()},
                                               path ::
                                                   #conn_path_mgmt{path_state ::
                                                                       nquic_path:state() | undefined,
                                                                   peer_cids ::
                                                                       #{non_neg_integer() =>
                                                                             #{cid :=
                                                                                   nquic:connection_id(),
                                                                               token := binary()}},
                                                                   local_cids ::
                                                                       #{non_neg_integer() =>
                                                                             nquic:connection_id()},
                                                                   local_cid_seq :: non_neg_integer(),
                                                                   peer_retire_prior_to ::
                                                                       non_neg_integer(),
                                                                   anti_amp_bytes_received ::
                                                                       non_neg_integer(),
                                                                   anti_amp_bytes_sent ::
                                                                       non_neg_integer(),
                                                                   address_validated :: boolean()}}.

initiate_client_migration/2

-spec initiate_client_migration(nquic_socket:sockaddr(),
                                #conn_state{role :: client | server,
                                            scid :: nquic:connection_id(),
                                            dcid :: nquic:connection_id(),
                                            odcid :: nquic:connection_id() | undefined,
                                            retry_scid :: nquic:connection_id() | undefined,
                                            retry_token :: binary(),
                                            version :: non_neg_integer(),
                                            version_preference :: [non_neg_integer()],
                                            socket :: nquic_socket:t() | undefined,
                                            peer :: nquic_socket:sockaddr() | undefined,
                                            select_info :: nquic_socket:select_info() | undefined,
                                            pn_spaces :: #{nquic_packet:space() => map()},
                                            app_next_pn :: non_neg_integer(),
                                            app_largest_received :: integer(),
                                            loss_state :: nquic_loss:loss_state() | undefined,
                                            dispatch_table :: nquic_dispatch:t() | undefined,
                                            listener :: pid() | undefined,
                                            connect_waiters :: [gen_server:from()],
                                            local_params ::
                                                #transport_params{original_destination_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  max_idle_timeout :: non_neg_integer(),
                                                                  stateless_reset_token ::
                                                                      binary() | undefined,
                                                                  max_udp_payload_size :: pos_integer(),
                                                                  initial_max_data :: non_neg_integer(),
                                                                  initial_max_stream_data_bidi_local ::
                                                                      non_neg_integer(),
                                                                  initial_max_stream_data_bidi_remote ::
                                                                      non_neg_integer(),
                                                                  initial_max_stream_data_uni ::
                                                                      non_neg_integer(),
                                                                  initial_max_streams_bidi ::
                                                                      non_neg_integer(),
                                                                  initial_max_streams_uni ::
                                                                      non_neg_integer(),
                                                                  ack_delay_exponent :: 0..20,
                                                                  max_ack_delay :: non_neg_integer(),
                                                                  disable_active_migration :: boolean(),
                                                                  preferred_address ::
                                                                      nquic_transport:preferred_address() |
                                                                      undefined,
                                                                  active_connection_id_limit ::
                                                                      non_neg_integer(),
                                                                  initial_source_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  retry_source_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  version_information ::
                                                                      nquic_transport:version_information() |
                                                                      undefined,
                                                                  max_datagram_frame_size ::
                                                                      non_neg_integer() | undefined},
                                            remote_params ::
                                                #transport_params{original_destination_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  max_idle_timeout :: non_neg_integer(),
                                                                  stateless_reset_token ::
                                                                      binary() | undefined,
                                                                  max_udp_payload_size :: pos_integer(),
                                                                  initial_max_data :: non_neg_integer(),
                                                                  initial_max_stream_data_bidi_local ::
                                                                      non_neg_integer(),
                                                                  initial_max_stream_data_bidi_remote ::
                                                                      non_neg_integer(),
                                                                  initial_max_stream_data_uni ::
                                                                      non_neg_integer(),
                                                                  initial_max_streams_bidi ::
                                                                      non_neg_integer(),
                                                                  initial_max_streams_uni ::
                                                                      non_neg_integer(),
                                                                  ack_delay_exponent :: 0..20,
                                                                  max_ack_delay :: non_neg_integer(),
                                                                  disable_active_migration :: boolean(),
                                                                  preferred_address ::
                                                                      nquic_transport:preferred_address() |
                                                                      undefined,
                                                                  active_connection_id_limit ::
                                                                      non_neg_integer(),
                                                                  initial_source_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  retry_source_connection_id ::
                                                                      nquic:connection_id() | undefined,
                                                                  version_information ::
                                                                      nquic_transport:version_information() |
                                                                      undefined,
                                                                  max_datagram_frame_size ::
                                                                      non_neg_integer() | undefined} |
                                                undefined,
                                            server_packet_processed :: boolean(),
                                            owner :: pid() | undefined,
                                            owner_mon :: reference() | undefined,
                                            deferred_flush_pending :: boolean(),
                                            pending_ack_count :: non_neg_integer(),
                                            last_idle_ms :: non_neg_integer() | infinity | undefined,
                                            last_pto_ms :: non_neg_integer() | cancel | undefined,
                                            recv_ecn :: nquic_socket:ecn_mark(),
                                            pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                            gso_size :: undefined | pos_integer(),
                                            max_payload_size :: pos_integer(),
                                            server_per_conn_fd :: boolean(),
                                            proactive_cids :: boolean(),
                                            socket_connected :: boolean(),
                                            self_migration_pending :: boolean(),
                                            metrics_counters ::
                                                nquic_metrics:conn_counters() | undefined,
                                            spin_enabled :: boolean(),
                                            peer_spin :: 0..1,
                                            new_token_enabled :: boolean(),
                                            new_token_lifetime :: pos_integer(),
                                            qlog :: undefined | nquic_qlog:qlog_state(),
                                            close_kind ::
                                                undefined | local | peer | idle_timeout | protocol_error,
                                            crypto ::
                                                #conn_crypto{tls_state :: term(),
                                                             keys ::
                                                                 #{nquic_packet:space() | rtt0 => map()},
                                                             app_send_keys :: map() | undefined,
                                                             app_recv_keys :: map() | undefined,
                                                             crypto_buffer ::
                                                                 #{nquic_packet:space() =>
                                                                       {non_neg_integer(),
                                                                        binary(),
                                                                        list()}},
                                                             cipher ::
                                                                 aes_128_gcm | aes_256_gcm |
                                                                 chacha20_poly1305,
                                                             cipher_suites ::
                                                                 [aes_128_gcm | aes_256_gcm |
                                                                  chacha20_poly1305] |
                                                                 undefined,
                                                             key_phase :: boolean(),
                                                             key_update_pending :: boolean(),
                                                             client_app_secret :: binary() | undefined,
                                                             server_app_secret :: binary() | undefined,
                                                             old_read_keys ::
                                                                 #{key := binary(), iv := binary()} |
                                                                 undefined,
                                                             zero_rtt_accepted :: boolean(),
                                                             replay_protection :: module() | undefined,
                                                             session_ticket :: map() | undefined,
                                                             resumption_secret :: binary() | undefined,
                                                             session_cache ::
                                                                 atom() |
                                                                 false |
                                                                 {module, module()} |
                                                                 undefined,
                                                             token_cache ::
                                                                 atom() | false | {module, module()},
                                                             alpn :: [binary()] | undefined,
                                                             hostname :: string() | binary() | undefined,
                                                             cert :: binary() | undefined,
                                                             cert_chain :: [binary()],
                                                             key :: any() | undefined,
                                                             verify :: verify_none | verify_peer,
                                                             cacerts :: [binary()],
                                                             peer_cert :: binary() | undefined,
                                                             static_key :: binary() | undefined},
                                            streams_state ::
                                                #conn_streams{streams ::
                                                                  #{nquic:stream_id() =>
                                                                        #stream_state{stream_id ::
                                                                                          nquic:stream_id(),
                                                                                      type :: bidi | uni,
                                                                                      send_state ::
                                                                                          ready | send |
                                                                                          data_sent |
                                                                                          data_recvd |
                                                                                          reset_sent |
                                                                                          reset_recvd,
                                                                                      send_offset ::
                                                                                          non_neg_integer(),
                                                                                      send_max_data ::
                                                                                          non_neg_integer(),
                                                                                      last_stream_data_blocked ::
                                                                                          non_neg_integer(),
                                                                                      pending_send_data ::
                                                                                          [binary()],
                                                                                      pending_send_size ::
                                                                                          non_neg_integer(),
                                                                                      pending_send_fin ::
                                                                                          boolean(),
                                                                                      recv_state ::
                                                                                          recv |
                                                                                          size_known |
                                                                                          data_recvd |
                                                                                          reset_recvd |
                                                                                          data_read |
                                                                                          reset_read,
                                                                                      recv_offset ::
                                                                                          non_neg_integer(),
                                                                                      recv_max_offset ::
                                                                                          non_neg_integer(),
                                                                                      recv_window ::
                                                                                          non_neg_integer(),
                                                                                      recv_buffer ::
                                                                                          gb_trees:tree(non_neg_integer(),
                                                                                                        {binary(),
                                                                                                         boolean()}),
                                                                                      app_buffer ::
                                                                                          iodata(),
                                                                                      app_buffer_size ::
                                                                                          non_neg_integer()}},
                                                              next_bidi_stream ::
                                                                  nquic:stream_id() | undefined,
                                                              next_uni_stream ::
                                                                  nquic:stream_id() | undefined,
                                                              peer_max_streams_bidi :: non_neg_integer(),
                                                              peer_max_streams_uni :: non_neg_integer(),
                                                              local_max_streams_bidi ::
                                                                  non_neg_integer(),
                                                              local_max_streams_uni :: non_neg_integer(),
                                                              last_sent_max_streams_bidi ::
                                                                  non_neg_integer(),
                                                              last_sent_max_streams_uni ::
                                                                  non_neg_integer(),
                                                              max_peer_bidi_stream_id ::
                                                                  non_neg_integer() | undefined,
                                                              max_peer_uni_stream_id ::
                                                                  non_neg_integer() | undefined,
                                                              opened_peer_bidi_count ::
                                                                  non_neg_integer(),
                                                              opened_peer_uni_count :: non_neg_integer(),
                                                              closed_peer_bidi_wm :: integer(),
                                                              closed_peer_uni_wm :: integer(),
                                                              closed_peer_streams ::
                                                                  #{nquic:stream_id() => true},
                                                              recv_waiters ::
                                                                  #{nquic:stream_id() =>
                                                                        gen_statem:from()},
                                                              accept_stream_waiters ::
                                                                  queue:queue(gen_statem:from()),
                                                              pending_streams ::
                                                                  queue:queue(nquic:stream_id()),
                                                              blocked_streams ::
                                                                  #{nquic:stream_id() => true},
                                                              pending_send_streams ::
                                                                  #{nquic:stream_id() => true},
                                                              send_buffer_high_water :: pos_integer(),
                                                              send_timeout :: timeout(),
                                                              send_waiters ::
                                                                  queue:queue(nquic_conn_send_waiters:t())},
                                            flow ::
                                                #conn_flow{local_max_data :: non_neg_integer(),
                                                           remote_max_data :: non_neg_integer(),
                                                           data_sent :: non_neg_integer(),
                                                           data_received :: non_neg_integer(),
                                                           last_data_blocked :: non_neg_integer(),
                                                           pending_initial_frames :: [nquic_frame:t()],
                                                           pending_handshake_frames :: [nquic_frame:t()],
                                                           pending_app_frames :: [nquic_frame:t()],
                                                           pending_app_pre_encoded ::
                                                               [{non_neg_integer(),
                                                                 iodata(),
                                                                 nquic_frame:t()}],
                                                           queued_app_send_bytes :: non_neg_integer()},
                                            path ::
                                                #conn_path_mgmt{path_state ::
                                                                    nquic_path:state() | undefined,
                                                                peer_cids ::
                                                                    #{non_neg_integer() =>
                                                                          #{cid := nquic:connection_id(),
                                                                            token := binary()}},
                                                                local_cids ::
                                                                    #{non_neg_integer() =>
                                                                          nquic:connection_id()},
                                                                local_cid_seq :: non_neg_integer(),
                                                                peer_retire_prior_to ::
                                                                    non_neg_integer(),
                                                                anti_amp_bytes_received ::
                                                                    non_neg_integer(),
                                                                anti_amp_bytes_sent :: non_neg_integer(),
                                                                address_validated :: boolean()}}) ->
                                   {ok,
                                    #conn_state{role :: client | server,
                                                scid :: nquic:connection_id(),
                                                dcid :: nquic:connection_id(),
                                                odcid :: nquic:connection_id() | undefined,
                                                retry_scid :: nquic:connection_id() | undefined,
                                                retry_token :: binary(),
                                                version :: non_neg_integer(),
                                                version_preference :: [non_neg_integer()],
                                                socket :: nquic_socket:t() | undefined,
                                                peer :: nquic_socket:sockaddr() | undefined,
                                                select_info :: nquic_socket:select_info() | undefined,
                                                pn_spaces :: #{nquic_packet:space() => map()},
                                                app_next_pn :: non_neg_integer(),
                                                app_largest_received :: integer(),
                                                loss_state :: nquic_loss:loss_state() | undefined,
                                                dispatch_table :: nquic_dispatch:t() | undefined,
                                                listener :: pid() | undefined,
                                                connect_waiters :: [gen_server:from()],
                                                local_params ::
                                                    #transport_params{original_destination_connection_id ::
                                                                          nquic:connection_id() |
                                                                          undefined,
                                                                      max_idle_timeout ::
                                                                          non_neg_integer(),
                                                                      stateless_reset_token ::
                                                                          binary() | undefined,
                                                                      max_udp_payload_size ::
                                                                          pos_integer(),
                                                                      initial_max_data ::
                                                                          non_neg_integer(),
                                                                      initial_max_stream_data_bidi_local ::
                                                                          non_neg_integer(),
                                                                      initial_max_stream_data_bidi_remote ::
                                                                          non_neg_integer(),
                                                                      initial_max_stream_data_uni ::
                                                                          non_neg_integer(),
                                                                      initial_max_streams_bidi ::
                                                                          non_neg_integer(),
                                                                      initial_max_streams_uni ::
                                                                          non_neg_integer(),
                                                                      ack_delay_exponent :: 0..20,
                                                                      max_ack_delay :: non_neg_integer(),
                                                                      disable_active_migration ::
                                                                          boolean(),
                                                                      preferred_address ::
                                                                          nquic_transport:preferred_address() |
                                                                          undefined,
                                                                      active_connection_id_limit ::
                                                                          non_neg_integer(),
                                                                      initial_source_connection_id ::
                                                                          nquic:connection_id() |
                                                                          undefined,
                                                                      retry_source_connection_id ::
                                                                          nquic:connection_id() |
                                                                          undefined,
                                                                      version_information ::
                                                                          nquic_transport:version_information() |
                                                                          undefined,
                                                                      max_datagram_frame_size ::
                                                                          non_neg_integer() | undefined},
                                                remote_params ::
                                                    #transport_params{original_destination_connection_id ::
                                                                          nquic:connection_id() |
                                                                          undefined,
                                                                      max_idle_timeout ::
                                                                          non_neg_integer(),
                                                                      stateless_reset_token ::
                                                                          binary() | undefined,
                                                                      max_udp_payload_size ::
                                                                          pos_integer(),
                                                                      initial_max_data ::
                                                                          non_neg_integer(),
                                                                      initial_max_stream_data_bidi_local ::
                                                                          non_neg_integer(),
                                                                      initial_max_stream_data_bidi_remote ::
                                                                          non_neg_integer(),
                                                                      initial_max_stream_data_uni ::
                                                                          non_neg_integer(),
                                                                      initial_max_streams_bidi ::
                                                                          non_neg_integer(),
                                                                      initial_max_streams_uni ::
                                                                          non_neg_integer(),
                                                                      ack_delay_exponent :: 0..20,
                                                                      max_ack_delay :: non_neg_integer(),
                                                                      disable_active_migration ::
                                                                          boolean(),
                                                                      preferred_address ::
                                                                          nquic_transport:preferred_address() |
                                                                          undefined,
                                                                      active_connection_id_limit ::
                                                                          non_neg_integer(),
                                                                      initial_source_connection_id ::
                                                                          nquic:connection_id() |
                                                                          undefined,
                                                                      retry_source_connection_id ::
                                                                          nquic:connection_id() |
                                                                          undefined,
                                                                      version_information ::
                                                                          nquic_transport:version_information() |
                                                                          undefined,
                                                                      max_datagram_frame_size ::
                                                                          non_neg_integer() | undefined} |
                                                    undefined,
                                                server_packet_processed :: boolean(),
                                                owner :: pid() | undefined,
                                                owner_mon :: reference() | undefined,
                                                deferred_flush_pending :: boolean(),
                                                pending_ack_count :: non_neg_integer(),
                                                last_idle_ms :: non_neg_integer() | infinity | undefined,
                                                last_pto_ms :: non_neg_integer() | cancel | undefined,
                                                recv_ecn :: nquic_socket:ecn_mark(),
                                                pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                                gso_size :: undefined | pos_integer(),
                                                max_payload_size :: pos_integer(),
                                                server_per_conn_fd :: boolean(),
                                                proactive_cids :: boolean(),
                                                socket_connected :: boolean(),
                                                self_migration_pending :: boolean(),
                                                metrics_counters ::
                                                    nquic_metrics:conn_counters() | undefined,
                                                spin_enabled :: boolean(),
                                                peer_spin :: 0..1,
                                                new_token_enabled :: boolean(),
                                                new_token_lifetime :: pos_integer(),
                                                qlog :: undefined | nquic_qlog:qlog_state(),
                                                close_kind ::
                                                    undefined | local | peer | idle_timeout |
                                                    protocol_error,
                                                crypto ::
                                                    #conn_crypto{tls_state :: term(),
                                                                 keys ::
                                                                     #{nquic_packet:space() | rtt0 =>
                                                                           map()},
                                                                 app_send_keys :: map() | undefined,
                                                                 app_recv_keys :: map() | undefined,
                                                                 crypto_buffer ::
                                                                     #{nquic_packet:space() =>
                                                                           {non_neg_integer(),
                                                                            binary(),
                                                                            list()}},
                                                                 cipher ::
                                                                     aes_128_gcm | aes_256_gcm |
                                                                     chacha20_poly1305,
                                                                 cipher_suites ::
                                                                     [aes_128_gcm | aes_256_gcm |
                                                                      chacha20_poly1305] |
                                                                     undefined,
                                                                 key_phase :: boolean(),
                                                                 key_update_pending :: boolean(),
                                                                 client_app_secret ::
                                                                     binary() | undefined,
                                                                 server_app_secret ::
                                                                     binary() | undefined,
                                                                 old_read_keys ::
                                                                     #{key := binary(), iv := binary()} |
                                                                     undefined,
                                                                 zero_rtt_accepted :: boolean(),
                                                                 replay_protection ::
                                                                     module() | undefined,
                                                                 session_ticket :: map() | undefined,
                                                                 resumption_secret ::
                                                                     binary() | undefined,
                                                                 session_cache ::
                                                                     atom() |
                                                                     false |
                                                                     {module, module()} |
                                                                     undefined,
                                                                 token_cache ::
                                                                     atom() | false | {module, module()},
                                                                 alpn :: [binary()] | undefined,
                                                                 hostname ::
                                                                     string() | binary() | undefined,
                                                                 cert :: binary() | undefined,
                                                                 cert_chain :: [binary()],
                                                                 key :: any() | undefined,
                                                                 verify :: verify_none | verify_peer,
                                                                 cacerts :: [binary()],
                                                                 peer_cert :: binary() | undefined,
                                                                 static_key :: binary() | undefined},
                                                streams_state ::
                                                    #conn_streams{streams ::
                                                                      #{nquic:stream_id() =>
                                                                            #stream_state{stream_id ::
                                                                                              nquic:stream_id(),
                                                                                          type ::
                                                                                              bidi | uni,
                                                                                          send_state ::
                                                                                              ready |
                                                                                              send |
                                                                                              data_sent |
                                                                                              data_recvd |
                                                                                              reset_sent |
                                                                                              reset_recvd,
                                                                                          send_offset ::
                                                                                              non_neg_integer(),
                                                                                          send_max_data ::
                                                                                              non_neg_integer(),
                                                                                          last_stream_data_blocked ::
                                                                                              non_neg_integer(),
                                                                                          pending_send_data ::
                                                                                              [binary()],
                                                                                          pending_send_size ::
                                                                                              non_neg_integer(),
                                                                                          pending_send_fin ::
                                                                                              boolean(),
                                                                                          recv_state ::
                                                                                              recv |
                                                                                              size_known |
                                                                                              data_recvd |
                                                                                              reset_recvd |
                                                                                              data_read |
                                                                                              reset_read,
                                                                                          recv_offset ::
                                                                                              non_neg_integer(),
                                                                                          recv_max_offset ::
                                                                                              non_neg_integer(),
                                                                                          recv_window ::
                                                                                              non_neg_integer(),
                                                                                          recv_buffer ::
                                                                                              gb_trees:tree(non_neg_integer(),
                                                                                                            {binary(),
                                                                                                             boolean()}),
                                                                                          app_buffer ::
                                                                                              iodata(),
                                                                                          app_buffer_size ::
                                                                                              non_neg_integer()}},
                                                                  next_bidi_stream ::
                                                                      nquic:stream_id() | undefined,
                                                                  next_uni_stream ::
                                                                      nquic:stream_id() | undefined,
                                                                  peer_max_streams_bidi ::
                                                                      non_neg_integer(),
                                                                  peer_max_streams_uni ::
                                                                      non_neg_integer(),
                                                                  local_max_streams_bidi ::
                                                                      non_neg_integer(),
                                                                  local_max_streams_uni ::
                                                                      non_neg_integer(),
                                                                  last_sent_max_streams_bidi ::
                                                                      non_neg_integer(),
                                                                  last_sent_max_streams_uni ::
                                                                      non_neg_integer(),
                                                                  max_peer_bidi_stream_id ::
                                                                      non_neg_integer() | undefined,
                                                                  max_peer_uni_stream_id ::
                                                                      non_neg_integer() | undefined,
                                                                  opened_peer_bidi_count ::
                                                                      non_neg_integer(),
                                                                  opened_peer_uni_count ::
                                                                      non_neg_integer(),
                                                                  closed_peer_bidi_wm :: integer(),
                                                                  closed_peer_uni_wm :: integer(),
                                                                  closed_peer_streams ::
                                                                      #{nquic:stream_id() => true},
                                                                  recv_waiters ::
                                                                      #{nquic:stream_id() =>
                                                                            gen_statem:from()},
                                                                  accept_stream_waiters ::
                                                                      queue:queue(gen_statem:from()),
                                                                  pending_streams ::
                                                                      queue:queue(nquic:stream_id()),
                                                                  blocked_streams ::
                                                                      #{nquic:stream_id() => true},
                                                                  pending_send_streams ::
                                                                      #{nquic:stream_id() => true},
                                                                  send_buffer_high_water ::
                                                                      pos_integer(),
                                                                  send_timeout :: timeout(),
                                                                  send_waiters ::
                                                                      queue:queue(nquic_conn_send_waiters:t())},
                                                flow ::
                                                    #conn_flow{local_max_data :: non_neg_integer(),
                                                               remote_max_data :: non_neg_integer(),
                                                               data_sent :: non_neg_integer(),
                                                               data_received :: non_neg_integer(),
                                                               last_data_blocked :: non_neg_integer(),
                                                               pending_initial_frames ::
                                                                   [nquic_frame:t()],
                                                               pending_handshake_frames ::
                                                                   [nquic_frame:t()],
                                                               pending_app_frames :: [nquic_frame:t()],
                                                               pending_app_pre_encoded ::
                                                                   [{non_neg_integer(),
                                                                     iodata(),
                                                                     nquic_frame:t()}],
                                                               queued_app_send_bytes ::
                                                                   non_neg_integer()},
                                                path ::
                                                    #conn_path_mgmt{path_state ::
                                                                        nquic_path:state() | undefined,
                                                                    peer_cids ::
                                                                        #{non_neg_integer() =>
                                                                              #{cid :=
                                                                                    nquic:connection_id(),
                                                                                token := binary()}},
                                                                    local_cids ::
                                                                        #{non_neg_integer() =>
                                                                              nquic:connection_id()},
                                                                    local_cid_seq :: non_neg_integer(),
                                                                    peer_retire_prior_to ::
                                                                        non_neg_integer(),
                                                                    anti_amp_bytes_received ::
                                                                        non_neg_integer(),
                                                                    anti_amp_bytes_sent ::
                                                                        non_neg_integer(),
                                                                    address_validated :: boolean()}}} |
                                   {error, term()}.

Rebind the client socket and queue a PATH_CHALLENGE for the new path. The challenge is left queued; the statem caller flushes.

maybe_initiate_server_migration/1

-spec maybe_initiate_server_migration(#conn_state{role :: client | server,
                                                  scid :: nquic:connection_id(),
                                                  dcid :: nquic:connection_id(),
                                                  odcid :: nquic:connection_id() | undefined,
                                                  retry_scid :: nquic:connection_id() | undefined,
                                                  retry_token :: binary(),
                                                  version :: non_neg_integer(),
                                                  version_preference :: [non_neg_integer()],
                                                  socket :: nquic_socket:t() | undefined,
                                                  peer :: nquic_socket:sockaddr() | undefined,
                                                  select_info :: nquic_socket:select_info() | undefined,
                                                  pn_spaces :: #{nquic_packet:space() => map()},
                                                  app_next_pn :: non_neg_integer(),
                                                  app_largest_received :: integer(),
                                                  loss_state :: nquic_loss:loss_state() | undefined,
                                                  dispatch_table :: nquic_dispatch:t() | undefined,
                                                  listener :: pid() | undefined,
                                                  connect_waiters :: [gen_server:from()],
                                                  local_params ::
                                                      #transport_params{original_destination_connection_id ::
                                                                            nquic:connection_id() |
                                                                            undefined,
                                                                        max_idle_timeout ::
                                                                            non_neg_integer(),
                                                                        stateless_reset_token ::
                                                                            binary() | undefined,
                                                                        max_udp_payload_size ::
                                                                            pos_integer(),
                                                                        initial_max_data ::
                                                                            non_neg_integer(),
                                                                        initial_max_stream_data_bidi_local ::
                                                                            non_neg_integer(),
                                                                        initial_max_stream_data_bidi_remote ::
                                                                            non_neg_integer(),
                                                                        initial_max_stream_data_uni ::
                                                                            non_neg_integer(),
                                                                        initial_max_streams_bidi ::
                                                                            non_neg_integer(),
                                                                        initial_max_streams_uni ::
                                                                            non_neg_integer(),
                                                                        ack_delay_exponent :: 0..20,
                                                                        max_ack_delay ::
                                                                            non_neg_integer(),
                                                                        disable_active_migration ::
                                                                            boolean(),
                                                                        preferred_address ::
                                                                            nquic_transport:preferred_address() |
                                                                            undefined,
                                                                        active_connection_id_limit ::
                                                                            non_neg_integer(),
                                                                        initial_source_connection_id ::
                                                                            nquic:connection_id() |
                                                                            undefined,
                                                                        retry_source_connection_id ::
                                                                            nquic:connection_id() |
                                                                            undefined,
                                                                        version_information ::
                                                                            nquic_transport:version_information() |
                                                                            undefined,
                                                                        max_datagram_frame_size ::
                                                                            non_neg_integer() |
                                                                            undefined},
                                                  remote_params ::
                                                      #transport_params{original_destination_connection_id ::
                                                                            nquic:connection_id() |
                                                                            undefined,
                                                                        max_idle_timeout ::
                                                                            non_neg_integer(),
                                                                        stateless_reset_token ::
                                                                            binary() | undefined,
                                                                        max_udp_payload_size ::
                                                                            pos_integer(),
                                                                        initial_max_data ::
                                                                            non_neg_integer(),
                                                                        initial_max_stream_data_bidi_local ::
                                                                            non_neg_integer(),
                                                                        initial_max_stream_data_bidi_remote ::
                                                                            non_neg_integer(),
                                                                        initial_max_stream_data_uni ::
                                                                            non_neg_integer(),
                                                                        initial_max_streams_bidi ::
                                                                            non_neg_integer(),
                                                                        initial_max_streams_uni ::
                                                                            non_neg_integer(),
                                                                        ack_delay_exponent :: 0..20,
                                                                        max_ack_delay ::
                                                                            non_neg_integer(),
                                                                        disable_active_migration ::
                                                                            boolean(),
                                                                        preferred_address ::
                                                                            nquic_transport:preferred_address() |
                                                                            undefined,
                                                                        active_connection_id_limit ::
                                                                            non_neg_integer(),
                                                                        initial_source_connection_id ::
                                                                            nquic:connection_id() |
                                                                            undefined,
                                                                        retry_source_connection_id ::
                                                                            nquic:connection_id() |
                                                                            undefined,
                                                                        version_information ::
                                                                            nquic_transport:version_information() |
                                                                            undefined,
                                                                        max_datagram_frame_size ::
                                                                            non_neg_integer() |
                                                                            undefined} |
                                                      undefined,
                                                  server_packet_processed :: boolean(),
                                                  owner :: pid() | undefined,
                                                  owner_mon :: reference() | undefined,
                                                  deferred_flush_pending :: boolean(),
                                                  pending_ack_count :: non_neg_integer(),
                                                  last_idle_ms ::
                                                      non_neg_integer() | infinity | undefined,
                                                  last_pto_ms :: non_neg_integer() | cancel | undefined,
                                                  recv_ecn :: nquic_socket:ecn_mark(),
                                                  pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                                  gso_size :: undefined | pos_integer(),
                                                  max_payload_size :: pos_integer(),
                                                  server_per_conn_fd :: boolean(),
                                                  proactive_cids :: boolean(),
                                                  socket_connected :: boolean(),
                                                  self_migration_pending :: boolean(),
                                                  metrics_counters ::
                                                      nquic_metrics:conn_counters() | undefined,
                                                  spin_enabled :: boolean(),
                                                  peer_spin :: 0..1,
                                                  new_token_enabled :: boolean(),
                                                  new_token_lifetime :: pos_integer(),
                                                  qlog :: undefined | nquic_qlog:qlog_state(),
                                                  close_kind ::
                                                      undefined | local | peer | idle_timeout |
                                                      protocol_error,
                                                  crypto ::
                                                      #conn_crypto{tls_state :: term(),
                                                                   keys ::
                                                                       #{nquic_packet:space() | rtt0 =>
                                                                             map()},
                                                                   app_send_keys :: map() | undefined,
                                                                   app_recv_keys :: map() | undefined,
                                                                   crypto_buffer ::
                                                                       #{nquic_packet:space() =>
                                                                             {non_neg_integer(),
                                                                              binary(),
                                                                              list()}},
                                                                   cipher ::
                                                                       aes_128_gcm | aes_256_gcm |
                                                                       chacha20_poly1305,
                                                                   cipher_suites ::
                                                                       [aes_128_gcm | aes_256_gcm |
                                                                        chacha20_poly1305] |
                                                                       undefined,
                                                                   key_phase :: boolean(),
                                                                   key_update_pending :: boolean(),
                                                                   client_app_secret ::
                                                                       binary() | undefined,
                                                                   server_app_secret ::
                                                                       binary() | undefined,
                                                                   old_read_keys ::
                                                                       #{key := binary(),
                                                                         iv := binary()} |
                                                                       undefined,
                                                                   zero_rtt_accepted :: boolean(),
                                                                   replay_protection ::
                                                                       module() | undefined,
                                                                   session_ticket :: map() | undefined,
                                                                   resumption_secret ::
                                                                       binary() | undefined,
                                                                   session_cache ::
                                                                       atom() |
                                                                       false |
                                                                       {module, module()} |
                                                                       undefined,
                                                                   token_cache ::
                                                                       atom() |
                                                                       false |
                                                                       {module, module()},
                                                                   alpn :: [binary()] | undefined,
                                                                   hostname ::
                                                                       string() | binary() | undefined,
                                                                   cert :: binary() | undefined,
                                                                   cert_chain :: [binary()],
                                                                   key :: any() | undefined,
                                                                   verify :: verify_none | verify_peer,
                                                                   cacerts :: [binary()],
                                                                   peer_cert :: binary() | undefined,
                                                                   static_key :: binary() | undefined},
                                                  streams_state ::
                                                      #conn_streams{streams ::
                                                                        #{nquic:stream_id() =>
                                                                              #stream_state{stream_id ::
                                                                                                nquic:stream_id(),
                                                                                            type ::
                                                                                                bidi |
                                                                                                uni,
                                                                                            send_state ::
                                                                                                ready |
                                                                                                send |
                                                                                                data_sent |
                                                                                                data_recvd |
                                                                                                reset_sent |
                                                                                                reset_recvd,
                                                                                            send_offset ::
                                                                                                non_neg_integer(),
                                                                                            send_max_data ::
                                                                                                non_neg_integer(),
                                                                                            last_stream_data_blocked ::
                                                                                                non_neg_integer(),
                                                                                            pending_send_data ::
                                                                                                [binary()],
                                                                                            pending_send_size ::
                                                                                                non_neg_integer(),
                                                                                            pending_send_fin ::
                                                                                                boolean(),
                                                                                            recv_state ::
                                                                                                recv |
                                                                                                size_known |
                                                                                                data_recvd |
                                                                                                reset_recvd |
                                                                                                data_read |
                                                                                                reset_read,
                                                                                            recv_offset ::
                                                                                                non_neg_integer(),
                                                                                            recv_max_offset ::
                                                                                                non_neg_integer(),
                                                                                            recv_window ::
                                                                                                non_neg_integer(),
                                                                                            recv_buffer ::
                                                                                                gb_trees:tree(non_neg_integer(),
                                                                                                              {binary(),
                                                                                                               boolean()}),
                                                                                            app_buffer ::
                                                                                                iodata(),
                                                                                            app_buffer_size ::
                                                                                                non_neg_integer()}},
                                                                    next_bidi_stream ::
                                                                        nquic:stream_id() | undefined,
                                                                    next_uni_stream ::
                                                                        nquic:stream_id() | undefined,
                                                                    peer_max_streams_bidi ::
                                                                        non_neg_integer(),
                                                                    peer_max_streams_uni ::
                                                                        non_neg_integer(),
                                                                    local_max_streams_bidi ::
                                                                        non_neg_integer(),
                                                                    local_max_streams_uni ::
                                                                        non_neg_integer(),
                                                                    last_sent_max_streams_bidi ::
                                                                        non_neg_integer(),
                                                                    last_sent_max_streams_uni ::
                                                                        non_neg_integer(),
                                                                    max_peer_bidi_stream_id ::
                                                                        non_neg_integer() | undefined,
                                                                    max_peer_uni_stream_id ::
                                                                        non_neg_integer() | undefined,
                                                                    opened_peer_bidi_count ::
                                                                        non_neg_integer(),
                                                                    opened_peer_uni_count ::
                                                                        non_neg_integer(),
                                                                    closed_peer_bidi_wm :: integer(),
                                                                    closed_peer_uni_wm :: integer(),
                                                                    closed_peer_streams ::
                                                                        #{nquic:stream_id() => true},
                                                                    recv_waiters ::
                                                                        #{nquic:stream_id() =>
                                                                              gen_statem:from()},
                                                                    accept_stream_waiters ::
                                                                        queue:queue(gen_statem:from()),
                                                                    pending_streams ::
                                                                        queue:queue(nquic:stream_id()),
                                                                    blocked_streams ::
                                                                        #{nquic:stream_id() => true},
                                                                    pending_send_streams ::
                                                                        #{nquic:stream_id() => true},
                                                                    send_buffer_high_water ::
                                                                        pos_integer(),
                                                                    send_timeout :: timeout(),
                                                                    send_waiters ::
                                                                        queue:queue(nquic_conn_send_waiters:t())},
                                                  flow ::
                                                      #conn_flow{local_max_data :: non_neg_integer(),
                                                                 remote_max_data :: non_neg_integer(),
                                                                 data_sent :: non_neg_integer(),
                                                                 data_received :: non_neg_integer(),
                                                                 last_data_blocked :: non_neg_integer(),
                                                                 pending_initial_frames ::
                                                                     [nquic_frame:t()],
                                                                 pending_handshake_frames ::
                                                                     [nquic_frame:t()],
                                                                 pending_app_frames :: [nquic_frame:t()],
                                                                 pending_app_pre_encoded ::
                                                                     [{non_neg_integer(),
                                                                       iodata(),
                                                                       nquic_frame:t()}],
                                                                 queued_app_send_bytes ::
                                                                     non_neg_integer()},
                                                  path ::
                                                      #conn_path_mgmt{path_state ::
                                                                          nquic_path:state() | undefined,
                                                                      peer_cids ::
                                                                          #{non_neg_integer() =>
                                                                                #{cid :=
                                                                                      nquic:connection_id(),
                                                                                  token := binary()}},
                                                                      local_cids ::
                                                                          #{non_neg_integer() =>
                                                                                nquic:connection_id()},
                                                                      local_cid_seq :: non_neg_integer(),
                                                                      peer_retire_prior_to ::
                                                                          non_neg_integer(),
                                                                      anti_amp_bytes_received ::
                                                                          non_neg_integer(),
                                                                      anti_amp_bytes_sent ::
                                                                          non_neg_integer(),
                                                                      address_validated :: boolean()}}) ->
                                         server_migration_result().

Attempt the server_per_conn_fd self-migration, returning a classified result. Logging is the statem's responsibility; noop means the connection was not eligible.

rotate_or_close(NewSocket, Data)

-spec rotate_or_close(nquic_socket:t(),
                      #conn_state{role :: client | server,
                                  scid :: nquic:connection_id(),
                                  dcid :: nquic:connection_id(),
                                  odcid :: nquic:connection_id() | undefined,
                                  retry_scid :: nquic:connection_id() | undefined,
                                  retry_token :: binary(),
                                  version :: non_neg_integer(),
                                  version_preference :: [non_neg_integer()],
                                  socket :: nquic_socket:t() | undefined,
                                  peer :: nquic_socket:sockaddr() | undefined,
                                  select_info :: nquic_socket:select_info() | undefined,
                                  pn_spaces :: #{nquic_packet:space() => map()},
                                  app_next_pn :: non_neg_integer(),
                                  app_largest_received :: integer(),
                                  loss_state :: nquic_loss:loss_state() | undefined,
                                  dispatch_table :: nquic_dispatch:t() | undefined,
                                  listener :: pid() | undefined,
                                  connect_waiters :: [gen_server:from()],
                                  local_params ::
                                      #transport_params{original_destination_connection_id ::
                                                            nquic:connection_id() | undefined,
                                                        max_idle_timeout :: non_neg_integer(),
                                                        stateless_reset_token :: binary() | undefined,
                                                        max_udp_payload_size :: pos_integer(),
                                                        initial_max_data :: non_neg_integer(),
                                                        initial_max_stream_data_bidi_local ::
                                                            non_neg_integer(),
                                                        initial_max_stream_data_bidi_remote ::
                                                            non_neg_integer(),
                                                        initial_max_stream_data_uni :: non_neg_integer(),
                                                        initial_max_streams_bidi :: non_neg_integer(),
                                                        initial_max_streams_uni :: non_neg_integer(),
                                                        ack_delay_exponent :: 0..20,
                                                        max_ack_delay :: non_neg_integer(),
                                                        disable_active_migration :: boolean(),
                                                        preferred_address ::
                                                            nquic_transport:preferred_address() |
                                                            undefined,
                                                        active_connection_id_limit :: non_neg_integer(),
                                                        initial_source_connection_id ::
                                                            nquic:connection_id() | undefined,
                                                        retry_source_connection_id ::
                                                            nquic:connection_id() | undefined,
                                                        version_information ::
                                                            nquic_transport:version_information() |
                                                            undefined,
                                                        max_datagram_frame_size ::
                                                            non_neg_integer() | undefined},
                                  remote_params ::
                                      #transport_params{original_destination_connection_id ::
                                                            nquic:connection_id() | undefined,
                                                        max_idle_timeout :: non_neg_integer(),
                                                        stateless_reset_token :: binary() | undefined,
                                                        max_udp_payload_size :: pos_integer(),
                                                        initial_max_data :: non_neg_integer(),
                                                        initial_max_stream_data_bidi_local ::
                                                            non_neg_integer(),
                                                        initial_max_stream_data_bidi_remote ::
                                                            non_neg_integer(),
                                                        initial_max_stream_data_uni :: non_neg_integer(),
                                                        initial_max_streams_bidi :: non_neg_integer(),
                                                        initial_max_streams_uni :: non_neg_integer(),
                                                        ack_delay_exponent :: 0..20,
                                                        max_ack_delay :: non_neg_integer(),
                                                        disable_active_migration :: boolean(),
                                                        preferred_address ::
                                                            nquic_transport:preferred_address() |
                                                            undefined,
                                                        active_connection_id_limit :: non_neg_integer(),
                                                        initial_source_connection_id ::
                                                            nquic:connection_id() | undefined,
                                                        retry_source_connection_id ::
                                                            nquic:connection_id() | undefined,
                                                        version_information ::
                                                            nquic_transport:version_information() |
                                                            undefined,
                                                        max_datagram_frame_size ::
                                                            non_neg_integer() | undefined} |
                                      undefined,
                                  server_packet_processed :: boolean(),
                                  owner :: pid() | undefined,
                                  owner_mon :: reference() | undefined,
                                  deferred_flush_pending :: boolean(),
                                  pending_ack_count :: non_neg_integer(),
                                  last_idle_ms :: non_neg_integer() | infinity | undefined,
                                  last_pto_ms :: non_neg_integer() | cancel | undefined,
                                  recv_ecn :: nquic_socket:ecn_mark(),
                                  pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                  gso_size :: undefined | pos_integer(),
                                  max_payload_size :: pos_integer(),
                                  server_per_conn_fd :: boolean(),
                                  proactive_cids :: boolean(),
                                  socket_connected :: boolean(),
                                  self_migration_pending :: boolean(),
                                  metrics_counters :: nquic_metrics:conn_counters() | undefined,
                                  spin_enabled :: boolean(),
                                  peer_spin :: 0..1,
                                  new_token_enabled :: boolean(),
                                  new_token_lifetime :: pos_integer(),
                                  qlog :: undefined | nquic_qlog:qlog_state(),
                                  close_kind :: undefined | local | peer | idle_timeout | protocol_error,
                                  crypto ::
                                      #conn_crypto{tls_state :: term(),
                                                   keys :: #{nquic_packet:space() | rtt0 => map()},
                                                   app_send_keys :: map() | undefined,
                                                   app_recv_keys :: map() | undefined,
                                                   crypto_buffer ::
                                                       #{nquic_packet:space() =>
                                                             {non_neg_integer(), binary(), list()}},
                                                   cipher ::
                                                       aes_128_gcm | aes_256_gcm | chacha20_poly1305,
                                                   cipher_suites ::
                                                       [aes_128_gcm | aes_256_gcm | chacha20_poly1305] |
                                                       undefined,
                                                   key_phase :: boolean(),
                                                   key_update_pending :: boolean(),
                                                   client_app_secret :: binary() | undefined,
                                                   server_app_secret :: binary() | undefined,
                                                   old_read_keys ::
                                                       #{key := binary(), iv := binary()} | undefined,
                                                   zero_rtt_accepted :: boolean(),
                                                   replay_protection :: module() | undefined,
                                                   session_ticket :: map() | undefined,
                                                   resumption_secret :: binary() | undefined,
                                                   session_cache ::
                                                       atom() | false | {module, module()} | undefined,
                                                   token_cache :: atom() | false | {module, module()},
                                                   alpn :: [binary()] | undefined,
                                                   hostname :: string() | binary() | undefined,
                                                   cert :: binary() | undefined,
                                                   cert_chain :: [binary()],
                                                   key :: any() | undefined,
                                                   verify :: verify_none | verify_peer,
                                                   cacerts :: [binary()],
                                                   peer_cert :: binary() | undefined,
                                                   static_key :: binary() | undefined},
                                  streams_state ::
                                      #conn_streams{streams ::
                                                        #{nquic:stream_id() =>
                                                              #stream_state{stream_id ::
                                                                                nquic:stream_id(),
                                                                            type :: bidi | uni,
                                                                            send_state ::
                                                                                ready | send |
                                                                                data_sent | data_recvd |
                                                                                reset_sent | reset_recvd,
                                                                            send_offset ::
                                                                                non_neg_integer(),
                                                                            send_max_data ::
                                                                                non_neg_integer(),
                                                                            last_stream_data_blocked ::
                                                                                non_neg_integer(),
                                                                            pending_send_data ::
                                                                                [binary()],
                                                                            pending_send_size ::
                                                                                non_neg_integer(),
                                                                            pending_send_fin ::
                                                                                boolean(),
                                                                            recv_state ::
                                                                                recv | size_known |
                                                                                data_recvd |
                                                                                reset_recvd |
                                                                                data_read | reset_read,
                                                                            recv_offset ::
                                                                                non_neg_integer(),
                                                                            recv_max_offset ::
                                                                                non_neg_integer(),
                                                                            recv_window ::
                                                                                non_neg_integer(),
                                                                            recv_buffer ::
                                                                                gb_trees:tree(non_neg_integer(),
                                                                                              {binary(),
                                                                                               boolean()}),
                                                                            app_buffer :: iodata(),
                                                                            app_buffer_size ::
                                                                                non_neg_integer()}},
                                                    next_bidi_stream :: nquic:stream_id() | undefined,
                                                    next_uni_stream :: nquic:stream_id() | undefined,
                                                    peer_max_streams_bidi :: non_neg_integer(),
                                                    peer_max_streams_uni :: non_neg_integer(),
                                                    local_max_streams_bidi :: non_neg_integer(),
                                                    local_max_streams_uni :: non_neg_integer(),
                                                    last_sent_max_streams_bidi :: non_neg_integer(),
                                                    last_sent_max_streams_uni :: non_neg_integer(),
                                                    max_peer_bidi_stream_id ::
                                                        non_neg_integer() | undefined,
                                                    max_peer_uni_stream_id ::
                                                        non_neg_integer() | undefined,
                                                    opened_peer_bidi_count :: non_neg_integer(),
                                                    opened_peer_uni_count :: non_neg_integer(),
                                                    closed_peer_bidi_wm :: integer(),
                                                    closed_peer_uni_wm :: integer(),
                                                    closed_peer_streams :: #{nquic:stream_id() => true},
                                                    recv_waiters ::
                                                        #{nquic:stream_id() => gen_statem:from()},
                                                    accept_stream_waiters ::
                                                        queue:queue(gen_statem:from()),
                                                    pending_streams :: queue:queue(nquic:stream_id()),
                                                    blocked_streams :: #{nquic:stream_id() => true},
                                                    pending_send_streams :: #{nquic:stream_id() => true},
                                                    send_buffer_high_water :: pos_integer(),
                                                    send_timeout :: timeout(),
                                                    send_waiters ::
                                                        queue:queue(nquic_conn_send_waiters:t())},
                                  flow ::
                                      #conn_flow{local_max_data :: non_neg_integer(),
                                                 remote_max_data :: non_neg_integer(),
                                                 data_sent :: non_neg_integer(),
                                                 data_received :: non_neg_integer(),
                                                 last_data_blocked :: non_neg_integer(),
                                                 pending_initial_frames :: [nquic_frame:t()],
                                                 pending_handshake_frames :: [nquic_frame:t()],
                                                 pending_app_frames :: [nquic_frame:t()],
                                                 pending_app_pre_encoded ::
                                                     [{non_neg_integer(), iodata(), nquic_frame:t()}],
                                                 queued_app_send_bytes :: non_neg_integer()},
                                  path ::
                                      #conn_path_mgmt{path_state :: nquic_path:state() | undefined,
                                                      peer_cids ::
                                                          #{non_neg_integer() =>
                                                                #{cid := nquic:connection_id(),
                                                                  token := binary()}},
                                                      local_cids ::
                                                          #{non_neg_integer() => nquic:connection_id()},
                                                      local_cid_seq :: non_neg_integer(),
                                                      peer_retire_prior_to :: non_neg_integer(),
                                                      anti_amp_bytes_received :: non_neg_integer(),
                                                      anti_amp_bytes_sent :: non_neg_integer(),
                                                      address_validated :: boolean()}}) ->
                         {ok,
                          #conn_state{role :: client | server,
                                      scid :: nquic:connection_id(),
                                      dcid :: nquic:connection_id(),
                                      odcid :: nquic:connection_id() | undefined,
                                      retry_scid :: nquic:connection_id() | undefined,
                                      retry_token :: binary(),
                                      version :: non_neg_integer(),
                                      version_preference :: [non_neg_integer()],
                                      socket :: nquic_socket:t() | undefined,
                                      peer :: nquic_socket:sockaddr() | undefined,
                                      select_info :: nquic_socket:select_info() | undefined,
                                      pn_spaces :: #{nquic_packet:space() => map()},
                                      app_next_pn :: non_neg_integer(),
                                      app_largest_received :: integer(),
                                      loss_state :: nquic_loss:loss_state() | undefined,
                                      dispatch_table :: nquic_dispatch:t() | undefined,
                                      listener :: pid() | undefined,
                                      connect_waiters :: [gen_server:from()],
                                      local_params ::
                                          #transport_params{original_destination_connection_id ::
                                                                nquic:connection_id() | undefined,
                                                            max_idle_timeout :: non_neg_integer(),
                                                            stateless_reset_token ::
                                                                binary() | undefined,
                                                            max_udp_payload_size :: pos_integer(),
                                                            initial_max_data :: non_neg_integer(),
                                                            initial_max_stream_data_bidi_local ::
                                                                non_neg_integer(),
                                                            initial_max_stream_data_bidi_remote ::
                                                                non_neg_integer(),
                                                            initial_max_stream_data_uni ::
                                                                non_neg_integer(),
                                                            initial_max_streams_bidi ::
                                                                non_neg_integer(),
                                                            initial_max_streams_uni :: non_neg_integer(),
                                                            ack_delay_exponent :: 0..20,
                                                            max_ack_delay :: non_neg_integer(),
                                                            disable_active_migration :: boolean(),
                                                            preferred_address ::
                                                                nquic_transport:preferred_address() |
                                                                undefined,
                                                            active_connection_id_limit ::
                                                                non_neg_integer(),
                                                            initial_source_connection_id ::
                                                                nquic:connection_id() | undefined,
                                                            retry_source_connection_id ::
                                                                nquic:connection_id() | undefined,
                                                            version_information ::
                                                                nquic_transport:version_information() |
                                                                undefined,
                                                            max_datagram_frame_size ::
                                                                non_neg_integer() | undefined},
                                      remote_params ::
                                          #transport_params{original_destination_connection_id ::
                                                                nquic:connection_id() | undefined,
                                                            max_idle_timeout :: non_neg_integer(),
                                                            stateless_reset_token ::
                                                                binary() | undefined,
                                                            max_udp_payload_size :: pos_integer(),
                                                            initial_max_data :: non_neg_integer(),
                                                            initial_max_stream_data_bidi_local ::
                                                                non_neg_integer(),
                                                            initial_max_stream_data_bidi_remote ::
                                                                non_neg_integer(),
                                                            initial_max_stream_data_uni ::
                                                                non_neg_integer(),
                                                            initial_max_streams_bidi ::
                                                                non_neg_integer(),
                                                            initial_max_streams_uni :: non_neg_integer(),
                                                            ack_delay_exponent :: 0..20,
                                                            max_ack_delay :: non_neg_integer(),
                                                            disable_active_migration :: boolean(),
                                                            preferred_address ::
                                                                nquic_transport:preferred_address() |
                                                                undefined,
                                                            active_connection_id_limit ::
                                                                non_neg_integer(),
                                                            initial_source_connection_id ::
                                                                nquic:connection_id() | undefined,
                                                            retry_source_connection_id ::
                                                                nquic:connection_id() | undefined,
                                                            version_information ::
                                                                nquic_transport:version_information() |
                                                                undefined,
                                                            max_datagram_frame_size ::
                                                                non_neg_integer() | undefined} |
                                          undefined,
                                      server_packet_processed :: boolean(),
                                      owner :: pid() | undefined,
                                      owner_mon :: reference() | undefined,
                                      deferred_flush_pending :: boolean(),
                                      pending_ack_count :: non_neg_integer(),
                                      last_idle_ms :: non_neg_integer() | infinity | undefined,
                                      last_pto_ms :: non_neg_integer() | cancel | undefined,
                                      recv_ecn :: nquic_socket:ecn_mark(),
                                      pmtud :: nquic_pmtud:pmtud_state() | undefined,
                                      gso_size :: undefined | pos_integer(),
                                      max_payload_size :: pos_integer(),
                                      server_per_conn_fd :: boolean(),
                                      proactive_cids :: boolean(),
                                      socket_connected :: boolean(),
                                      self_migration_pending :: boolean(),
                                      metrics_counters :: nquic_metrics:conn_counters() | undefined,
                                      spin_enabled :: boolean(),
                                      peer_spin :: 0..1,
                                      new_token_enabled :: boolean(),
                                      new_token_lifetime :: pos_integer(),
                                      qlog :: undefined | nquic_qlog:qlog_state(),
                                      close_kind ::
                                          undefined | local | peer | idle_timeout | protocol_error,
                                      crypto ::
                                          #conn_crypto{tls_state :: term(),
                                                       keys :: #{nquic_packet:space() | rtt0 => map()},
                                                       app_send_keys :: map() | undefined,
                                                       app_recv_keys :: map() | undefined,
                                                       crypto_buffer ::
                                                           #{nquic_packet:space() =>
                                                                 {non_neg_integer(), binary(), list()}},
                                                       cipher ::
                                                           aes_128_gcm | aes_256_gcm | chacha20_poly1305,
                                                       cipher_suites ::
                                                           [aes_128_gcm | aes_256_gcm |
                                                            chacha20_poly1305] |
                                                           undefined,
                                                       key_phase :: boolean(),
                                                       key_update_pending :: boolean(),
                                                       client_app_secret :: binary() | undefined,
                                                       server_app_secret :: binary() | undefined,
                                                       old_read_keys ::
                                                           #{key := binary(), iv := binary()} |
                                                           undefined,
                                                       zero_rtt_accepted :: boolean(),
                                                       replay_protection :: module() | undefined,
                                                       session_ticket :: map() | undefined,
                                                       resumption_secret :: binary() | undefined,
                                                       session_cache ::
                                                           atom() |
                                                           false |
                                                           {module, module()} |
                                                           undefined,
                                                       token_cache ::
                                                           atom() | false | {module, module()},
                                                       alpn :: [binary()] | undefined,
                                                       hostname :: string() | binary() | undefined,
                                                       cert :: binary() | undefined,
                                                       cert_chain :: [binary()],
                                                       key :: any() | undefined,
                                                       verify :: verify_none | verify_peer,
                                                       cacerts :: [binary()],
                                                       peer_cert :: binary() | undefined,
                                                       static_key :: binary() | undefined},
                                      streams_state ::
                                          #conn_streams{streams ::
                                                            #{nquic:stream_id() =>
                                                                  #stream_state{stream_id ::
                                                                                    nquic:stream_id(),
                                                                                type :: bidi | uni,
                                                                                send_state ::
                                                                                    ready | send |
                                                                                    data_sent |
                                                                                    data_recvd |
                                                                                    reset_sent |
                                                                                    reset_recvd,
                                                                                send_offset ::
                                                                                    non_neg_integer(),
                                                                                send_max_data ::
                                                                                    non_neg_integer(),
                                                                                last_stream_data_blocked ::
                                                                                    non_neg_integer(),
                                                                                pending_send_data ::
                                                                                    [binary()],
                                                                                pending_send_size ::
                                                                                    non_neg_integer(),
                                                                                pending_send_fin ::
                                                                                    boolean(),
                                                                                recv_state ::
                                                                                    recv | size_known |
                                                                                    data_recvd |
                                                                                    reset_recvd |
                                                                                    data_read |
                                                                                    reset_read,
                                                                                recv_offset ::
                                                                                    non_neg_integer(),
                                                                                recv_max_offset ::
                                                                                    non_neg_integer(),
                                                                                recv_window ::
                                                                                    non_neg_integer(),
                                                                                recv_buffer ::
                                                                                    gb_trees:tree(non_neg_integer(),
                                                                                                  {binary(),
                                                                                                   boolean()}),
                                                                                app_buffer :: iodata(),
                                                                                app_buffer_size ::
                                                                                    non_neg_integer()}},
                                                        next_bidi_stream ::
                                                            nquic:stream_id() | undefined,
                                                        next_uni_stream :: nquic:stream_id() | undefined,
                                                        peer_max_streams_bidi :: non_neg_integer(),
                                                        peer_max_streams_uni :: non_neg_integer(),
                                                        local_max_streams_bidi :: non_neg_integer(),
                                                        local_max_streams_uni :: non_neg_integer(),
                                                        last_sent_max_streams_bidi :: non_neg_integer(),
                                                        last_sent_max_streams_uni :: non_neg_integer(),
                                                        max_peer_bidi_stream_id ::
                                                            non_neg_integer() | undefined,
                                                        max_peer_uni_stream_id ::
                                                            non_neg_integer() | undefined,
                                                        opened_peer_bidi_count :: non_neg_integer(),
                                                        opened_peer_uni_count :: non_neg_integer(),
                                                        closed_peer_bidi_wm :: integer(),
                                                        closed_peer_uni_wm :: integer(),
                                                        closed_peer_streams ::
                                                            #{nquic:stream_id() => true},
                                                        recv_waiters ::
                                                            #{nquic:stream_id() => gen_statem:from()},
                                                        accept_stream_waiters ::
                                                            queue:queue(gen_statem:from()),
                                                        pending_streams ::
                                                            queue:queue(nquic:stream_id()),
                                                        blocked_streams :: #{nquic:stream_id() => true},
                                                        pending_send_streams ::
                                                            #{nquic:stream_id() => true},
                                                        send_buffer_high_water :: pos_integer(),
                                                        send_timeout :: timeout(),
                                                        send_waiters ::
                                                            queue:queue(nquic_conn_send_waiters:t())},
                                      flow ::
                                          #conn_flow{local_max_data :: non_neg_integer(),
                                                     remote_max_data :: non_neg_integer(),
                                                     data_sent :: non_neg_integer(),
                                                     data_received :: non_neg_integer(),
                                                     last_data_blocked :: non_neg_integer(),
                                                     pending_initial_frames :: [nquic_frame:t()],
                                                     pending_handshake_frames :: [nquic_frame:t()],
                                                     pending_app_frames :: [nquic_frame:t()],
                                                     pending_app_pre_encoded ::
                                                         [{non_neg_integer(), iodata(), nquic_frame:t()}],
                                                     queued_app_send_bytes :: non_neg_integer()},
                                      path ::
                                          #conn_path_mgmt{path_state :: nquic_path:state() | undefined,
                                                          peer_cids ::
                                                              #{non_neg_integer() =>
                                                                    #{cid := nquic:connection_id(),
                                                                      token := binary()}},
                                                          local_cids ::
                                                              #{non_neg_integer() =>
                                                                    nquic:connection_id()},
                                                          local_cid_seq :: non_neg_integer(),
                                                          peer_retire_prior_to :: non_neg_integer(),
                                                          anti_amp_bytes_received :: non_neg_integer(),
                                                          anti_amp_bytes_sent :: non_neg_integer(),
                                                          address_validated :: boolean()}}} |
                         {error, no_available_cids}.