LCOV - code coverage report
Current view: top level - waltz/quic - fd_quic.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 5 21 23.8 %
Date: 2025-07-01 05:00:49 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_quic_fd_quic_h
       2             : #define HEADER_fd_src_waltz_quic_fd_quic_h
       3             : 
       4             : /* fd_quic_t is a partial implementation of QUIC -- an encrypted,
       5             :    multiplexing transport layer network protocol.
       6             : 
       7             :    For now, IPv4 over Ethernet (EN10MB) flows are supported.
       8             : 
       9             :    This API is non-blocking and single-threaded.  Any requests to the
      10             :    peer (such as "open a connection") are queued and processed on RX
      11             :    or service call.  The user is notified of events via callbacks.
      12             :    The user must further ensure that RX (via fd_aio_t) is dispatched
      13             :    only from the thread with the active join to the target fd_quic_t.
      14             : 
      15             :    Scaling is achieved via fd_quic_t instances and steering of RX flows.
      16             :    For example, incoming RX that exceeds the throughput of one fd_quic_t
      17             :    may be load balanced based on QUIC dest conn ID, or UDP src flow ID.
      18             : 
      19             :    This implementation aims to be compliant to RFC 9000 and RFC 9001:
      20             :    - https://datatracker.ietf.org/doc/html/rfc9000
      21             :    - https://datatracker.ietf.org/doc/html/rfc9001
      22             : 
      23             :    ### Memory Management
      24             : 
      25             :    fd_quic is entirely pre-allocated.  Currently, a QUIC object reserves
      26             :    space for a number of connection slots, with uniform stream,
      27             :    reassembly, and ACK buffers.
      28             : 
      29             :    ### Memory Layout
      30             : 
      31             :    fd_quic_t is the publicly exported memory layout of a QUIC object.
      32             :    The private memory region of a QUIC object extends beyond the end of
      33             :    this struct.  fd_quic_t is not intended to be allocated directly,
      34             :    refer to the below for details.
      35             : 
      36             :    ### Lifecycle
      37             : 
      38             :    The below state diagram shows the lifecycle of an fd_quic_t.
      39             : 
      40             :       ┌───────────┐  new   ┌───────────┐ join  ┌──────────┐
      41             :       │           ├───────►│           ├──────►│          │
      42             :       │ allocated │        │ formatted │       │  joined  │
      43             :       │           │◄───────┤           │◄──────┤          │
      44             :       └───────────┘ delete └───────────┘ leave └───▲───┬──┘
      45             :                                                    │   │ set config
      46             :                                                    │   │ set callbacks
      47             :                                               fini │   │ init
      48             :                                                 ┌──┴───▼──┐
      49             :                                             ┌───│         │
      50             :                                     service │   │  ready  │
      51             :                                             └──►│         │
      52             :                                                 └─────────┘
      53             : 
      54             :    ### Lifecycle: Allocation & Formatting
      55             : 
      56             :    A QUIC object resides in a contiguous pre-allocated memory region.
      57             :    (Usually, in a Firedancer workspace)  The footprint and internal
      58             :    layout depends on the pre-configured fd_quic_limits_t parameters.
      59             :    These limits are constant throughout the lifetime of an fd_quic_t.
      60             : 
      61             :    Use fd_quic_{align,footprint} to determine size and alignment of the
      62             :    memory region to be used.  Use fd_quic_new to format such a memory
      63             :    region and to obtain an opaque handle.  In the formatted state, the
      64             :    fd_quic_t is position-independent (may be mapped at different virtual
      65             :    addresses).  This is useful for separating allocation and runtime use
      66             :    into different steps.
      67             : 
      68             :    ### Lifecycle: Joining
      69             : 
      70             :    Given an opaque handle, fd_quic_join runs basic coherence checks and
      71             :    returns a typed pointer to the object.  The object is not modified
      72             :    by this operation.  Each object may have multiple active joins, but
      73             :    only one of them may write.  (Typically, a single join is used for
      74             :    service, and secondary joins for read-only monitoring)
      75             : 
      76             :    ### Lifecycle: Usage
      77             : 
      78             :    fd_quic_init initializes an fd_quic_t for use.  On success, the QUIC
      79             :    becomes ready to serve from the thread that init was called from (it
      80             :    is invalid to service QUIC from another thread). */
      81             : 
      82             : /* TODO provide fd_quic on non-hosted targets */
      83             : 
      84             : #include "fd_quic_common.h"
      85             : #include "fd_quic_enum.h"
      86             : 
      87             : #include "../aio/fd_aio.h"
      88             : #include "../tls/fd_tls.h"
      89             : #include "../../util/hist/fd_histf.h"
      90             : 
      91             : /* FD_QUIC_API marks public API declarations.  No-op for now. */
      92             : #define FD_QUIC_API
      93             : 
      94             : /* Forward declarations */
      95             : 
      96             : struct fd_quic_conn;
      97             : typedef struct fd_quic_conn fd_quic_conn_t;
      98             : 
      99             : struct fd_quic_stream;
     100             : typedef struct fd_quic_stream fd_quic_stream_t;
     101             : 
     102             : struct fd_quic_state_private;
     103             : typedef struct fd_quic_state_private fd_quic_state_t;
     104             : 
     105             : /* fd_quic_limits_t defines the memory layout of an fd_quic_t object.
     106             :    Limits are immutable and valid for the lifetime of an fd_quic_t
     107             :    (i.e. outlasts joins, until fd_quic_delete) */
     108             : 
     109             : struct __attribute__((aligned(16UL))) fd_quic_limits {
     110             :   ulong  conn_cnt;                  /* instance-wide, max concurrent conn count       */
     111             :   ulong  handshake_cnt;             /* instance-wide, max concurrent handshake count  */
     112             :   ulong  log_depth;                 /* instance-wide, depth of shm log cache          */
     113             : 
     114             :   ulong  conn_id_cnt;                 /* per-conn, max conn ID count (min 4UL)          */
     115             :   ulong  stream_id_cnt;               /* per-conn, max concurrent stream ID count       */
     116             :   ulong  inflight_frame_cnt;          /* instance-wide, total max inflight frame count  */
     117             :   ulong  min_inflight_frame_cnt_conn; /* per-conn, min inflight frame count             */
     118             : 
     119             :   ulong  tx_buf_sz;                 /* per-stream, tx buf sz in bytes                 */
     120             :   /* the user consumes rx directly from the network buffer */
     121             : 
     122             :   ulong  stream_pool_cnt;           /* instance-wide, number of streams in stream pool */
     123             : };
     124             : typedef struct fd_quic_limits fd_quic_limits_t;
     125             : 
     126             : /* fd_quic_layout_t is an offset table describing the memory layout of
     127             :    an fd_quic_t object.  It is deived from fd_quic_limits_t. */
     128             : 
     129             : struct fd_quic_layout {
     130             :   ulong meta_sz;           /* size of this struct */
     131             :   ulong log_off;           /* offset to quic_log */
     132             :   ulong conns_off;         /* offset of connection mem region  */
     133             :   ulong conn_footprint;    /* sizeof a conn                    */
     134             :   ulong conn_map_off;      /* offset of conn map mem region    */
     135             :   int   lg_slot_cnt;       /* see conn_map_new                 */
     136             :   ulong hs_pool_off;       /* offset of the handshake pool     */
     137             :   ulong stream_pool_off;   /* offset of the stream pool        */
     138             :   ulong pkt_meta_pool_off; /* offset of the pkt_meta pool      */
     139             : };
     140             : 
     141             : typedef struct fd_quic_layout fd_quic_layout_t;
     142             : 
     143             : /* fd_quic_now_t is the clock source used internally by quic for
     144             :    scheduling events.  context is an arbitrary pointer earlier provided
     145             :    by the caller during config. */
     146             : 
     147             : typedef ulong
     148             : (*fd_quic_now_t)( void * context );
     149             : 
     150             : /* fd_quic_config_t defines mutable config of an fd_quic_t.  The config is
     151             :    immutable during an active join. */
     152             : 
     153             : struct __attribute__((aligned(16UL))) fd_quic_config {
     154             :   /* Used by tracing/logging code */
     155             : #define FD_QUIC_CONFIG_ENUM_LIST_role(X,...) \
     156             :   X( FD_QUIC_ROLE_CLIENT, "ROLE_CLIENT" )    \
     157             :   X( FD_QUIC_ROLE_SERVER, "ROLE_SERVER" )
     158             : 
     159             : #define FD_QUIC_CONFIG_LIST(X,...) \
     160           0 :   X( role,                        "%d",     enum,  "enum",         __VA_ARGS__ ) \
     161           0 :   X( retry,                       "%d",     bool,  "bool",         __VA_ARGS__ ) \
     162           0 :   X( tick_per_us,                 "%f",     units, "ticks per ms", __VA_ARGS__ ) \
     163           0 :   X( idle_timeout,                "%lu",    units, "ns",           __VA_ARGS__ ) \
     164           0 :   X( keep_alive,                  "%d",     bool,  "bool",         __VA_ARGS__ ) \
     165           0 :   X( ack_delay,                   "%lu",    units, "ns",           __VA_ARGS__ ) \
     166           0 :   X( ack_threshold,               "%lu",    units, "bytes",        __VA_ARGS__ ) \
     167           0 :   X( retry_ttl,                   "%lu",    units, "ns",           __VA_ARGS__ ) \
     168           0 :   X( tls_hs_ttl,                  "%lu",    units, "ns",           __VA_ARGS__ ) \
     169           0 :   X( identity_public_key,         "%x",     hex32, "",             __VA_ARGS__ ) \
     170           0 :   X( sign,                        "%p",     ptr,   "",             __VA_ARGS__ ) \
     171           0 :   X( sign_ctx,                    "%p",     ptr,   "",             __VA_ARGS__ ) \
     172           0 :   X( keylog_file,                 "%s",     value, "",             __VA_ARGS__ ) \
     173           0 :   X( initial_rx_max_stream_data,  "%lu",    units, "bytes",        __VA_ARGS__ ) \
     174           0 :   X( net.dscp,                    "0x%02x", value, "",             __VA_ARGS__ )
     175             : 
     176             :   /* Protocol config ***************************************/
     177             : 
     178             :   /* role: one of FD_QUIC_ROLE_{CLIENT,SERVER} */
     179             :   int role;
     180             : 
     181             :   /* retry: whether address validation using retry packets is enabled (RFC 9000, Section 8.1.2) */
     182             :   int retry;
     183             : 
     184             :   /* tick_per_us: clock ticks per microsecond */
     185             :   double tick_per_us;
     186             : 
     187             :   /* idle_timeout: Upper bound on conn idle timeout.
     188             :      Also sent to peer via max_idle_timeout transport param.
     189             :      If the peer specifies a lower idle timeout, that is used instead. */
     190             :   ulong idle_timeout;
     191        4272 : # define FD_QUIC_DEFAULT_IDLE_TIMEOUT (ulong)(1e9) /* 1s */
     192             : 
     193             : /* keep_alive
     194             :  * whether the fd_quic should use QUIC PING frames to keep connections alive
     195             :  * Set to 1 to keep connections alive
     196             :  * Set to 0 to allow connections to close on idle
     197             :  * default is 0 */
     198             :   int keep_alive;
     199             : 
     200             :   /* ack_delay: median delay on outgoing ACKs.  Greater delays allow
     201             :      fd_quic to coalesce packet ACKs. */
     202             :   ulong ack_delay;
     203        4272 : # define FD_QUIC_DEFAULT_ACK_DELAY (ulong)(50e6) /* 50ms */
     204             : 
     205             :   /* ack_threshold: immediately send an ACK when the number of
     206             :      unacknowledged stream bytes exceeds this value. */
     207             :   ulong ack_threshold;
     208        2142 : # define FD_QUIC_DEFAULT_ACK_THRESHOLD (65536UL) /* 64 KiB */
     209             : 
     210             :   /* retry_ttl: time-to-live for retry tokens */
     211             :   ulong retry_ttl;
     212        2139 : # define FD_QUIC_DEFAULT_RETRY_TTL (ulong)(1e9) /* 1s */
     213             : 
     214             :   /* hs_ttl: time-to-live for tls_hs */
     215             :   ulong tls_hs_ttl;
     216        2139 : # define FD_QUIC_DEFAULT_TLS_HS_TTL (ulong)(3e9) /* 3s */
     217             : 
     218             :   /* TLS config ********************************************/
     219             : 
     220             :   /* identity_key: Ed25519 public key of node identity */
     221             :   uchar identity_public_key[ 32 ];
     222             : 
     223             :   /* Callback for signing TLS 1.3 certificate verify payload */
     224             :   fd_tls_sign_fn_t sign;
     225             :   void *           sign_ctx;
     226             : 
     227           0 : # define FD_QUIC_PATH_LEN 1023UL
     228             :   char keylog_file[ FD_QUIC_PATH_LEN+1UL ];
     229             : 
     230             :   ulong initial_rx_max_stream_data; /* per-stream, rx buf sz in bytes, set by the user. */
     231             : 
     232             :   /* Network config ****************************************/
     233             : 
     234             :   struct { /* Internet config */
     235             :     /* dscp: Differentiated services code point.
     236             :        Set on all outgoing IPv4 packets. */
     237             :     uchar dscp;
     238             :   } net;
     239             : };
     240             : 
     241             : /* Callback API *******************************************************/
     242             : 
     243             : /* Note: QUIC library invokes callbacks during RX or service.  Callback
     244             :    may only invoke fd_quic API methods labelled CB-safe.  Callbacks are
     245             :    not re-entrant. */
     246             : 
     247             : /* fd_quic_cb_conn_new_t: server received a new conn and completed
     248             :    handshakes. */
     249             : typedef void
     250             : (* fd_quic_cb_conn_new_t)( fd_quic_conn_t * conn,
     251             :                            void *           quic_ctx );
     252             : 
     253             : /* fd_quic_cb_conn_handshake_complete_t: client completed a handshake
     254             :    of a conn it created. */
     255             : typedef void
     256             : (* fd_quic_cb_conn_handshake_complete_t)( fd_quic_conn_t * conn,
     257             :                                           void *           quic_ctx );
     258             : 
     259             : /* fd_quic_cb_conn_final_t: Conn termination notification.  The conn
     260             :    object is freed immediately after returning.  User should destroy any
     261             :    remaining references to conn in this callback. */
     262             : typedef void
     263             : (* fd_quic_cb_conn_final_t)( fd_quic_conn_t * conn,
     264             :                              void *           quic_ctx );
     265             : 
     266             : /* fd_quic_cb_stream_notify_t signals a notable stream event.
     267             :    stream_ctx object is the user-provided stream context set in the new
     268             :    callback.
     269             : 
     270             :    TODO will only one notify max be served?
     271             :    TODO will stream be deallocated immediately after callback?
     272             : 
     273             :    notify_type is one of FD_QUIC_NOTIFY_{...} */
     274             : typedef void
     275             : (* fd_quic_cb_stream_notify_t)( fd_quic_stream_t * stream,
     276             :                                 void *             stream_ctx,
     277             :                                 int                notify_type );
     278             : 
     279             : typedef int
     280             : (* fd_quic_cb_stream_rx_t)( fd_quic_conn_t * conn,
     281             :                             ulong            stream_id,
     282             :                             ulong            offset,
     283             :                             uchar const *    data,
     284             :                             ulong            data_sz,
     285             :                             int              fin );
     286             : 
     287             : /* fd_quic_cb_tls_keylog_t is called when a new encryption secret
     288             :    becomes available.  line is a cstr containing the secret in NSS key
     289             :    log format (intended for tests only). */
     290             : 
     291             : typedef void
     292             : (* fd_quic_cb_tls_keylog_t)( void *       quic_ctx,
     293             :                              char const * line );
     294             : 
     295             : /* fd_quic_callbacks_t defines the set of user-provided callbacks that
     296             :    are invoked by the QUIC library.  Resets on leave. */
     297             : 
     298             : struct fd_quic_callbacks {
     299             :   /* Function pointers to user callbacks */
     300             : 
     301             :   void * quic_ctx; /* user-provided context pointer
     302             :                       for instance-wide callbacks */
     303             : 
     304             :   fd_quic_cb_conn_new_t                conn_new;          /* non-NULL, with quic_ctx   */
     305             :   fd_quic_cb_conn_handshake_complete_t conn_hs_complete;  /* non-NULL, with quic_ctx   */
     306             :   fd_quic_cb_conn_final_t              conn_final;        /* non-NULL, with quic_ctx   */
     307             :   fd_quic_cb_stream_notify_t           stream_notify;     /* non-NULL, with stream_ctx */
     308             :   fd_quic_cb_stream_rx_t               stream_rx;         /* non-NULL, with stream_ctx */
     309             :   fd_quic_cb_tls_keylog_t              tls_keylog;        /* nullable, with quic_ctx   */
     310             : 
     311             :   /* Clock source */
     312             : 
     313             :   fd_quic_now_t now;     /* non-NULL */
     314             :   void *        now_ctx; /* user-provided context pointer for now_fn calls */
     315             : 
     316             : };
     317             : typedef struct fd_quic_callbacks fd_quic_callbacks_t;
     318             : 
     319             : /* fd_quic metrics ****************************************************/
     320             : 
     321             : /* TODO: evaluate performance impact of metrics */
     322             : 
     323             : union fd_quic_metrics {
     324             :   struct {
     325             :     /* Network metrics */
     326             :     ulong net_rx_pkt_cnt;  /* number of IP packets received */
     327             :     ulong net_rx_byte_cnt; /* total bytes received (including IP, UDP, QUIC headers) */
     328             :     ulong net_tx_pkt_cnt;  /* number of IP packets sent */
     329             :     ulong net_tx_byte_cnt; /* total bytes sent */
     330             :     ulong retry_tx_cnt;    /* number of Retry packets sent */
     331             : 
     332             :     /* Conn metrics */
     333             :     ulong conn_active_cnt;         /* number of active conns */
     334             :     ulong conn_created_cnt;        /* number of conns created */
     335             :     ulong conn_closed_cnt;         /* number of conns gracefully closed */
     336             :     ulong conn_aborted_cnt;        /* number of conns aborted */
     337             :     ulong conn_timeout_cnt;        /* number of conns timed out */
     338             :     ulong conn_retry_cnt;          /* number of conns established with retry */
     339             :     ulong conn_err_no_slots_cnt;   /* number of conns that failed to create due to lack of slots */
     340             :     ulong conn_err_retry_fail_cnt; /* number of conns that failed during retry (e.g. invalid token) */
     341             : 
     342             :     /* Packet metrics */
     343             :     ulong pkt_net_hdr_err_cnt;     /* number of packets dropped due to weird IPv4/UDP headers */
     344             :     ulong pkt_quic_hdr_err_cnt;    /* number of packets dropped due to weird QUIC header */
     345             :     ulong pkt_undersz_cnt;         /* number of QUIC packets dropped due to being too small */
     346             :     ulong pkt_oversz_cnt;          /* number of QUIC packets dropped due to being too large */
     347             :     ulong pkt_decrypt_fail_cnt[4]; /* number of packets that failed decryption due to auth tag */
     348             :     ulong pkt_no_key_cnt[4];       /* number of packets that failed decryption due to missing key */
     349             :     ulong pkt_no_conn_cnt;         /* number of packets with unknown conn ID (excl. Initial) */
     350             :     ulong frame_tx_alloc_cnt[3];   /* number of pkt_meta alloc successes, fails for empty pool, fails at conn max */
     351             :     ulong pkt_verneg_cnt;          /* number of QUIC version negotiation packets or packets with wrong version */
     352             :     ulong pkt_retransmissions_cnt; /* number of pkt_meta retries */
     353             : 
     354             :     /* Frame metrics */
     355             :     ulong frame_rx_cnt[ 22 ];      /* number of frames received (indexed by implementation-defined IDs) */
     356             :     ulong frame_rx_err_cnt;        /* number of frames failed */
     357             : 
     358             :     /* Handshake metrics */
     359             :     ulong hs_created_cnt;          /* number of handshake flows created */
     360             :     ulong hs_err_alloc_fail_cnt;   /* number of handshakes dropped due to alloc fail */
     361             :     ulong hs_evicted_cnt;          /* number of handshakes evicted */
     362             : 
     363             :     /* Stream metrics */
     364             :     ulong stream_opened_cnt;        /* number of streams opened */
     365             :     ulong stream_closed_cnt[5];     /* indexed by FD_QUIC_STREAM_NOTIFY_{...} */
     366             :     ulong stream_active_cnt;        /* number of active streams */
     367             :     ulong stream_rx_event_cnt;      /* number of stream RX events */
     368             :     ulong stream_rx_byte_cnt;       /* total stream payload bytes received */
     369             : 
     370             :     /* ACK metrics */
     371             :     ulong ack_tx[ 5 ];
     372             : 
     373             :     /* Performance metrics */
     374             :     fd_histf_t service_duration[ 1 ]; /* time spent in service */
     375             :     fd_histf_t receive_duration[ 1 ]; /* time spent in RX calls */
     376             :   };
     377             : };
     378             : typedef union fd_quic_metrics fd_quic_metrics_t;
     379             : 
     380             : /* fd_quic_t memory layout ********************************************/
     381             : 
     382             : struct fd_quic {
     383             :   ulong magic;   /* ==FD_QUIC_MAGIC */
     384             : 
     385             :   fd_quic_layout_t    layout;  /* position-independent, persistent,    read only */
     386             :   fd_quic_limits_t    limits;  /* position-independent, persistent,    read only */
     387             :   fd_quic_config_t    config;  /* position-independent, persistent,    writable pre init */
     388             :   fd_quic_callbacks_t cb;      /* position-dependent,   reset on join, writable pre init  */
     389             :   fd_quic_metrics_t   metrics; /* position-independent, persistent,    read only */
     390             : 
     391             :   fd_aio_t aio_rx; /* local AIO */
     392             :   fd_aio_t aio_tx; /* remote AIO */
     393             : 
     394             :   /* ... private variable-length structures follow ... */
     395             : };
     396             : 
     397             : FD_PROTOTYPES_BEGIN
     398             : 
     399             : /* Object lifecycle ***************************************************/
     400             : 
     401             : /* fd_quic_{align,footprint} return the required alignment and footprint
     402             :    of a memory region suitable for use as an fd_quic_t.  align returns
     403             :    FD_QUIC_ALIGN.  limits is a temporary reference to the requested
     404             : 
     405             :    On failure, footprint will silently return 0 (and thus can be used by
     406             :    the caller to validate fd_quic_new params) */
     407             : 
     408             : FD_QUIC_API FD_FN_CONST ulong
     409             : fd_quic_align( void );
     410             : 
     411             : FD_QUIC_API ulong
     412             : fd_quic_footprint( fd_quic_limits_t const * limits );
     413             : 
     414             : /* fd_quic_new formats an unused memory region for use as a QUIC client
     415             :    or server.  mem is a non-NULL pointer to this region in the local
     416             :    address with the required footprint and alignment.  limits is a
     417             :    temporary reference, identical to the one given to fd_quic_footprint
     418             :    used to figure out the required footprint. */
     419             : 
     420             : FD_QUIC_API void *
     421             : fd_quic_new( void *                   mem,
     422             :              fd_quic_limits_t const * limits );
     423             : 
     424             : /* fd_quic_join joins the caller to the fd_quic.  shquic points to the
     425             :    first byte of the memory region backing the QUIC in the caller's
     426             :    address space.
     427             : 
     428             :    Returns a pointer in the local address space to the public fd_quic_t
     429             :    region on success (do not assume this to be just a cast of shquic)
     430             :    and NULL on failure (logs details).  Reasons for failure are that
     431             :    shquic is obviously not a pointer to a correctly formatted QUIC
     432             :    object.  Every successful join should have a matching leave.  The
     433             :    lifetime of the join is until the matching leave or the thread group
     434             :    is terminated. */
     435             : 
     436             : FD_QUIC_API fd_quic_t *
     437             : fd_quic_join( void * shquic );
     438             : 
     439             : /* fd_quic_leave leaves a current local join and frees all dynamically
     440             :    managed resources (heap allocs, OS handles).  Returns the given quic
     441             :    on success and NULL on failure (logs details).  Reasons for failure
     442             :    include quic is NULL or no active join */
     443             : 
     444             : FD_QUIC_API void *
     445             : fd_quic_leave( fd_quic_t * quic );
     446             : 
     447             : /* fd_quic_delete unformats a memory region used as an fd_quic_t.
     448             :    Assumes nobody is joined to the region.  Returns the given quic
     449             :    pointer on success and NULL if used obviously in error (e.g. quic is
     450             :    obviously not an fd_quic_t ... logs details).  The ownership of the
     451             :    memory region is transferred ot the caller. */
     452             : 
     453             : FD_QUIC_API void *
     454             : fd_quic_delete( fd_quic_t * quic );
     455             : 
     456             : /* Configuration ******************************************************/
     457             : 
     458             : /* fd_quic_{limits,config}_from_env populates the given QUIC limits or
     459             :    config from command-line args and env vars.  If parg{c,v} are non-
     460             :    NULL, they are updated to strip the parsed args.  The last element of
     461             :    the *argv array must be NULL.  Returns given config on success and
     462             :    NULL on failure (logs details).  It is up to the caller to properly
     463             :    initialize the given limits/config. */
     464             : 
     465             : FD_QUIC_API fd_quic_limits_t *
     466             : fd_quic_limits_from_env( int  *   pargc,
     467             :                          char *** pargv,
     468             :                          fd_quic_limits_t * limits );
     469             : 
     470             : FD_QUIC_API fd_quic_config_t *
     471             : fd_quic_config_from_env( int  *   pargc,
     472             :                          char *** pargv,
     473             :                          fd_quic_config_t * config );
     474             : 
     475             : /* fd_quic_get_aio_net_rx returns this QUIC's aio base class.  Valid
     476             :    for lifetime of QUIC.  While pointer to aio can be obtained before
     477             :    init, calls to aio may only be dispatched by the thread with
     478             :    exclusive access to QUIC that owns it. */
     479             : 
     480             : FD_QUIC_API fd_aio_t const *
     481             : fd_quic_get_aio_net_rx( fd_quic_t * quic );
     482             : 
     483             : /* fd_quic_set_aio_net_tx sets the fd_aio_t used by the fd_quic_t to
     484             :    send tx data to the network driver.  Cleared on fini. */
     485             : 
     486             : FD_QUIC_API void
     487             : fd_quic_set_aio_net_tx( fd_quic_t *      quic,
     488             :                         fd_aio_t const * aio_tx );
     489             : 
     490             : /* fd_quic_set_clock sets the clock source.  Converts all timing values
     491             :    in the config to the new time scale. */
     492             : 
     493             : FD_QUIC_API void
     494             : fd_quic_set_clock( fd_quic_t *   quic,
     495             :                    fd_quic_now_t now_fn,
     496             :                    void *        now_ctx,
     497             :                    double        tick_per_us );
     498             : 
     499             : /* fd_quic_set_clock_tickcount sets fd_tickcount as the clock source. */
     500             : 
     501             : FD_QUIC_API void
     502             : fd_quic_set_clock_tickcount( fd_quic_t * quic );
     503             : 
     504             : /* Initialization *****************************************************/
     505             : 
     506             : /* fd_quic_init initializes the QUIC such that it is ready to serve.
     507             :    permits the calling thread exclusive access during which no other
     508             :    thread may write to the QUIC.  Exclusive rights get released when the
     509             :    thread exits or calls fd_quic_fini.
     510             : 
     511             :    Requires valid configuration and external objects (aio, callbacks).
     512             :    Returns given quic on success and NULL on failure (logs details).
     513             :    Performs various heap allocations and file system accesses such
     514             :    reading certs.  Reasons for failure include invalid config or
     515             :    fd_tls error. */
     516             : 
     517             : FD_QUIC_API fd_quic_t *
     518             : fd_quic_init( fd_quic_t * quic );
     519             : 
     520             : /* fd_quic_fini releases exclusive access over a QUIC.  Zero-initializes
     521             :    references to external objects (aio, callbacks).  Frees any heap
     522             :    allocs made by fd_quic_init.  Returns quic. */
     523             : 
     524             : FD_QUIC_API fd_quic_t *
     525             : fd_quic_fini( fd_quic_t * quic );
     526             : 
     527             : /* NOTE: Calling any of the below requires valid initialization from
     528             :    this thread group. */
     529             : 
     530             : /* Connection API *****************************************************/
     531             : 
     532             : /* fd_quic_connect initiates a new client connection to a remote QUIC
     533             :    server.  On success, returns a pointer to the conn object managed by
     534             :    QUIC.  On failure, returns NULL.  Reasons for failure include quic
     535             :    not a valid join or out of free conns.  Lifetime of returned conn is
     536             :    until conn_final callback.
     537             : 
     538             :    args
     539             :      dst_ip_addr   destination ip address
     540             :      dst_udp_port  destination port number */
     541             : 
     542             : FD_QUIC_API fd_quic_conn_t *
     543             : fd_quic_connect( fd_quic_t *  quic,  /* requires exclusive access */
     544             :                  uint         dst_ip_addr,
     545             :                  ushort       dst_udp_port,
     546             :                  uint         src_ip_addr,
     547             :                  ushort       src_udp_port );
     548             : 
     549             : /* fd_quic_conn_close asynchronously initiates a shutdown of the conn.
     550             :    The given reason code is returned to the peer via a CONNECTION_CLOSE
     551             :    frame, if possible.  Causes conn_final callback to be issued
     552             :    eventually. */
     553             : 
     554             : FD_QUIC_API void
     555             : fd_quic_conn_close( fd_quic_conn_t * conn,
     556             :                     uint             reason );
     557             : 
     558             : /* Service API ********************************************************/
     559             : 
     560             : /* fd_quic_get_next_wakeup returns the next requested service time.
     561             :    This is only intended for unit tests. */
     562             : 
     563             : FD_QUIC_API ulong
     564             : fd_quic_get_next_wakeup( fd_quic_t * quic );
     565             : 
     566             : /* fd_quic_service services the next QUIC connection, including stream
     567             :    transmit ops, ACK transmit, loss timeout, and idle timeout.   The
     568             :    user should call service at high frequency.  Returns 1 if the service
     569             :    call did any work, or 0 otherwise. */
     570             : 
     571             : FD_QUIC_API int
     572             : fd_quic_service( fd_quic_t * quic );
     573             : 
     574             : /* fd_quic_svc_validate checks for violations of service queue and free
     575             :    list invariants, such as cycles in linked lists.  Prints to warning/
     576             :    error log and exits the process if checks fail.  Intended for use in
     577             :    tests. */
     578             : 
     579             : void
     580             : fd_quic_svc_validate( fd_quic_t * quic );
     581             : 
     582             : /* Stream Send API ****************************************************/
     583             : 
     584             : /* fd_quic_conn_new_stream creates a new unidirectional stream on the
     585             :    given conn.  On success, returns the newly created stream.
     586             :    On failure, returns NULL.  Reasons for failure include invalid conn
     587             :    state or out of stream quota.
     588             : 
     589             :    The user does not own the returned pointer: its lifetime is managed
     590             :    by the connection. */
     591             : 
     592             : FD_QUIC_API fd_quic_stream_t *
     593             : fd_quic_conn_new_stream( fd_quic_conn_t * conn );
     594             : 
     595             : /* fd_quic_stream_send sends a chunk on a stream in order.
     596             : 
     597             :    Use fd_quic_conn_new_stream to create a new stream for sending
     598             :    or use the new stream callback to obtain a stream for replying.
     599             : 
     600             :    args
     601             :      stream         the stream to send on
     602             :      data           points to first byte of buffer (ignored if data_sz==0)
     603             :      data_sz        number of bytes to send
     604             :      fin            final: bool
     605             :                       set to indicate the stream is finalized by the last byte
     606             :                       in the batch
     607             :                       If the last buffer in the batch was rejected, the FIN
     608             :                         flag is not set, and may be applied in a future send
     609             :                         or via the fd_quic_stream_fin(...) function
     610             : 
     611             :    returns
     612             :        0   success
     613             :       <0   one of FD_QUIC_SEND_ERR_{INVAL_STREAM,INVAL_CONN,AGAIN} */
     614             : FD_QUIC_API int
     615             : fd_quic_stream_send( fd_quic_stream_t *  stream,
     616             :                      void const *        data,
     617             :                      ulong               data_sz,
     618             :                      int                 fin );
     619             : 
     620             : /* fd_quic_stream_fin: finish sending on a stream.  Called to signal
     621             :    no more data will be sent to self-to-peer flow of stream.  Peer may
     622             :    continue sending data on their side of the stream.  Caller should
     623             :    only call stream_fin once per stream, except when fin was already
     624             :    indicated via stream_send. */
     625             : 
     626             : FD_QUIC_API void
     627             : fd_quic_stream_fin( fd_quic_stream_t * stream );
     628             : 
     629             : FD_QUIC_API void
     630             : fd_quic_process_packet( fd_quic_t * quic,
     631             :                         uchar *     data,
     632             :                         ulong       data_sz );
     633             : 
     634             : uint
     635             : fd_quic_tx_buffered_raw( fd_quic_t * quic,
     636             :                          uchar **    tx_ptr_ptr,
     637             :                          uchar *     tx_buf,
     638             :                          ushort *    ipv4_id,
     639             :                          uint        dst_ipv4_addr,
     640             :                          ushort      dst_udp_port,
     641             :                          uint        src_ipv4_addr,
     642             :                          ushort      src_udp_port );
     643             : 
     644             : FD_PROTOTYPES_END
     645             : 
     646             : /* Convenience exports for consumers of API */
     647             : #include "fd_quic_conn.h"
     648             : #include "fd_quic_stream.h"
     649             : 
     650             : /* FD_DEBUG_MODE: set to enable debug-only code
     651             :    TODO move to util? */
     652             : #ifdef FD_DEBUG_MODE
     653             : #define FD_DEBUG(...) __VA_ARGS__
     654             : #else
     655             : #define FD_DEBUG(...)
     656             : #endif
     657             : 
     658             : #endif /* HEADER_fd_src_waltz_quic_fd_quic_h */

Generated by: LCOV version 1.14