View Source quicer_connection behaviour (quicer v0.0.303)

Quic Connection Behavior

Best practice for 1. server side connection acceptor

1. server side connection initiator

Summary

Callbacks

Handle connection closed. We don't have to terminate this process since connection could be resumed.
Handle connection handshake done callback is suggested to accept new streams @see quicer:accept_stream/3
Handle continue from other callbacks with callback state.
handle unhandled info with callback state.
Init Callback, after return should expect for recv new connection
Handle Local Addr Changed, currently not in use.
Handle new incoming connection request return {ok, cb_state()} to complete handshakereturn {error, Reason, cb_state()} to reject the new connection, this process will be terminatedNOTE: 1. If acceptor is supervised,new new acceptor will be spawned. 2. Connection maybe rejected in the stack earlier before this Callback.
Handle new stream from peer which has no owner assigned, or stream acceptor didn't accept the stream on time NOTE: The connection could start stream handoff procedure
Client only, New session ticket received,
Handle Peer Addr Changed
Handle Peer needs streams that peer could not start new stream due to local flow control.
Handle connection is resumed with 0-RTT SessionData contains session data was sent in 0-RTT
Handle connection shutdown initiated by peer
Handle Stream Available, reflect number of streams flow control at peer.
Handle connection shutdown due to transport error with error reason.NOTE: Cleanup is prefered to be handled in @see closed/3

Types

-type cb_ret() :: quicer_lib:cb_ret().
-type cb_state() :: quicer_lib:cb_state().
-type conf_handle() :: reference().
-type conn_opts() ::
    quic_settings() |
    #{alpn := [string()],
      conn_callback => module(),
      cert => filelib:filename(),
      certfile => filelib:filename(),
      key => filelib:filename(),
      keyfile => filelib:filename(),
      password => string(),
      verify => none | peer,
      handle => connection_handle(),
      nst => binary(),
      cacertfile => filelib:filename(),
      sslkeylogfile => filelib:filename(),
      peer_bidi_stream_count => uint16(),
      peer_unidi_stream_count => uint16(),
      handshake_idle_timeout_ms => non_neg_integer(),
      quic_event_mask => uint32(),
      param_conn_disable_1rtt_encryption => boolean(),
      param_conn_local_address => string()}.
-type connection_handle() :: reference().
-type global_handle() :: quic_global.
-type hostname() :: string().
-type listener_handle() :: reference().
-type quic_settings() ::
    #{max_bytes_per_key => uint64(),
      handshake_idle_timeout_ms => uint64(),
      idle_timeout_ms => uint64(),
      tls_client_max_send_buffer => uint32(),
      tls_server_max_send_buffer => uint32(),
      stream_recv_window_default => uint32(),
      stream_recv_buffer_default => uint32(),
      conn_flow_control_window => uint32(),
      max_stateless_operations => uint32(),
      initial_window_packets => uint32(),
      send_idle_timeout_ms => uint32(),
      initial_rtt_ms => uint32(),
      max_ack_delay_ms => uint32(),
      disconnect_timeout_ms => uint32(),
      keep_alive_interval_ms => uint32(),
      peer_bidi_stream_count => uint16(),
      peer_unidi_stream_count => uint16(),
      retry_memory_limit => uint16(),
      load_balancing_mode => uint16(),
      max_operations_per_drain => uint8(),
      send_buffering_enabled => uint8(),
      pacing_enabled => uint8(),
      migration_enabled => uint8(),
      datagram_receive_enabled => uint8(),
      server_resumption_level => uint8(),
      minimum_mtu => uint16(),
      maximum_mtu => uint16(),
      mtu_discovery_search_complete_timeout_us => uint64(),
      mtu_discovery_missing_probe_count => uint8(),
      max_binding_stateless_operations => uint16(),
      stateless_operation_expiration_ms => uint16()}.
-type reg_handle() :: reference().
-type send_flags() :: non_neg_integer().
-type state() ::
    #{listener := listener_handle(),
      conn := connection_handle(),
      callback := atom(),
      callback_state := term(),
      sup := undefined | pid(),
      conn_opts := map(),
      stream_opts := map(),
      is_resumed := boolean()}.
-type stream_handle() :: reference().
-type stream_open_flags() :: 0 | 1 | 2.
-type stream_opts() ::
    #{active := boolean() | once | integer(),
      open_flag => stream_open_flags(),
      start_flag => stream_start_flags(),
      event_mask => uint32(),
      disable_fpbuffer => boolean()}.
-type stream_start_flags() :: 0 | 1 | 2 | 4 | 8.
-type uint8() :: 0..1 bsl 8 - 1.
-type uint16() :: 0..1 bsl 16 - 1.
-type uint32() :: 0..1 bsl 32 - 1.
-type uint64() :: 0..1 bsl 64 - 1.

Callbacks

-callback closed(connection_handle(), conn_closed_props(), cb_state()) -> cb_ret().
Handle connection closed. We don't have to terminate this process since connection could be resumed.
-callback connected(connection_handle(), connected_props(), cb_state()) -> cb_ret().
Handle connection handshake done callback is suggested to accept new streams @see quicer:accept_stream/3
Link to this callback

handle_call/3

View Source (optional)
-callback handle_call(Req :: term(), From :: gen_server:from(), cb_state()) -> cb_ret().
Link to this callback

handle_continue/2

View Source (optional)
-callback handle_continue(Cont :: term(), cb_state()) -> cb_ret().
Handle continue from other callbacks with callback state.
Link to this callback

handle_info/2

View Source (optional)
-callback handle_info(Info :: term(), cb_state()) -> cb_ret().
handle unhandled info with callback state.
-callback init(cb_init_args()) -> {ok, cb_state()} | {error, app_error(), cb_state()}.
Init Callback, after return should expect for recv new connection
-callback local_address_changed(connection_handle(), quicer_addr(), cb_state()) -> cb_ret().
Handle Local Addr Changed, currently not in use.
-callback new_conn(connection_handle(), new_conn_props(), cb_state()) -> cb_ret().
Handle new incoming connection request return {ok, cb_state()} to complete handshakereturn {error, Reason, cb_state()} to reject the new connection, this process will be terminatedNOTE: 1. If acceptor is supervised,new new acceptor will be spawned. 2. Connection maybe rejected in the stack earlier before this Callback.
-callback new_stream(stream_handle(), new_stream_props(), cb_state()) -> cb_ret().
Handle new stream from peer which has no owner assigned, or stream acceptor didn't accept the stream on time NOTE: The connection could start stream handoff procedure
Link to this callback

nst_received/3

View Source (optional)
-callback nst_received(connection_handle(), TicketBin :: binary(), cb_state()) -> cb_ret().
Client only, New session ticket received,
-callback peer_address_changed(connection_handle(), quicer_addr(), cb_state) -> cb_ret().
Handle Peer Addr Changed
Link to this callback

peer_needs_streams/3

View Source (optional)
-callback peer_needs_streams(connection_handle(), unidi_streams | bidi_streams, cb_state()) -> cb_ret().
Handle Peer needs streams that peer could not start new stream due to local flow control.
-callback resumed(connection_handle(), SessionData :: binary() | false, cb_state()) -> cb_ret().
Handle connection is resumed with 0-RTT SessionData contains session data was sent in 0-RTT
-callback shutdown(connection_handle(), error_code(), cb_state()) -> cb_ret().
Handle connection shutdown initiated by peer
-callback streams_available(connection_handle(),
                  {BidirStreams :: non_neg_integer(), UnidirStreams :: non_neg_integer()},
                  cb_state()) ->
                     cb_ret().
Handle Stream Available, reflect number of streams flow control at peer.
-callback transport_shutdown(connection_handle(), transport_shutdown_props(), cb_state()) -> cb_ret().
Handle connection shutdown due to transport error with error reason.NOTE: Cleanup is prefered to be handled in @see closed/3

Functions

-spec get_cb_state(ConnPid :: pid()) -> {ok, cb_state()} | {error, any()}.
-spec get_handle(pid()) -> undefined | connection_handle().
get connection handle from quic connection process
Link to this function

handle_continue(Cont, State)

View Source
-spec handle_continue(Cont :: term(), State :: term()) ->
                   {noreply, NewState :: term()} |
                   {noreply, NewState :: term(), Timeout :: timeout()} |
                   {noreply, NewState :: term(), hibernate} |
                   {stop, Reason :: normal | term(), NewState :: term()}.
Link to this function

start_link(CallbackModule, Peer, Opts)

View Source
-spec start_link(atom(), {hostname(), inet:port_number()}, {conn_opts(), stream_opts()}) ->
              gen_server:start_ret().
Spawn Client connection or Start connection acceptor at server side
Link to this function

start_link(CallbackModule, Listener, ConnOpts, Sup)

View Source
-spec start_link(CallbackModule :: undefined | module(),
           Listener :: quicer:listener_handle(),
           ConnOpts :: term(),
           Sup :: pid()) ->
              {ok, Pid :: pid()} |
              {error, Error :: {already_started, pid()}} |
              {error, Error :: term()} |
              ignore.
Link to this function

stream_send(ConnPid, Callback, Data, SendFlag, StreamOpts, Timeout)

View Source
-spec stream_send(ConnPid :: pid(),
            Callback :: atom(),
            Data :: iodata(),
            SendFlag :: send_flags(),
            StreamOpts :: stream_opts(),
            timeout()) ->
               ok | {error, any()}.