nquic_session_ticket (nquic v1.0.0)

View Source

Client-side NewSessionTicket processing (RFC 8446 §4.6.1, RFC 9000 §7.4.1).

Decodes a post-handshake CRYPTO NewSessionTicket, derives the PSK from the resumption secret + ticket nonce, attaches the server's transport parameters (so a later 0-RTT connect can seed remote_params), persists the ticket via the configured session cache, and notifies the connection owner.

Summary

Functions

Process a received NewSessionTicket from post-handshake CRYPTO.

Functions

process_new_session_ticket/2

-spec process_new_session_ticket(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()}}) ->
                                    #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()}}.

Process a received NewSessionTicket from post-handshake CRYPTO.

Bin is the raw TLS handshake message (msgtype=4); anything else is returned untouched. Updates the connection state with the cached ticket map, persists to the configured session cache (if any), and sends `{quic_session_ticket, , _}` to the owner.