nquic_conn_streams (nquic v1.0.0)

View Source

Owner-waiter stream delivery for the handshake state machine.

Services recv_stream / accept_stream calls and wakes parked waiters when peer data or peer-opened streams arrive. Functions take #conn_state{} and return a library-shaped result; they never build gen_statem transitions or action lists; nquic_conn_statem wraps the reply_result() into the FSM result and owns the flush. The one exception is maybe_notify_recv_waiter/2's stream-cleanup path, which flushes via the shared nquic_conn_statem:flush_and_send/1 helper (the same cross-module helper nquic_conn_send_waiters and nquic_conn_timers use) because it runs inside the protocol-event fold, not a statem adapter.

Summary

Functions

Deliver buffered data to a parked recv waiter, if one exists. The size_known clause delivers the FIN marker and runs the stream cleanup path.

Hand a peer-initiated stream to a parked accept_stream waiter, or queue it for the next call.

Types

reply_result()

-type reply_result() ::
          {reply,
           term(),
           #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()}}} |
          {reply,
           term(),
           #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()}},
           flush} |
          {wait,
           #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

accept_stream(From, Data)

-spec accept_stream(gen_statem:from(),
                    #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()}}) ->
                       reply_result().

cache_new_token/2

-spec cache_new_token(binary(),
                      #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.

maybe_notify_recv_waiter(StreamID, Data)

-spec maybe_notify_recv_waiter(nquic:stream_id(),
                               #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()}}.

Deliver buffered data to a parked recv waiter, if one exists. The size_known clause delivers the FIN marker and runs the stream cleanup path.

notify_or_queue_stream(StreamID, Data)

-spec notify_or_queue_stream(nquic:stream_id(),
                             #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()}}.

Hand a peer-initiated stream to a parked accept_stream waiter, or queue it for the next call.

recv_stream(From, StreamID, Data)

-spec recv_stream(gen_statem:from(),
                  nquic:stream_id(),
                  #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()}}) ->
                     reply_result().

store_token/4

-spec store_token(atom() | {module, module()},
                  inet:hostname() | inet:ip_address(),
                  inet:port_number(),
                  binary()) ->
                     ok.