LCOV - code coverage report
Current view: top level - waltz/quic - fd_quic_conn.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 13 13 100.0 %
Date: 2024-11-13 11:58:15 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_quic_fd_quic_conn_h
       2             : #define HEADER_fd_src_waltz_quic_fd_quic_conn_h
       3             : 
       4             : #include "fd_quic.h"
       5             : #include "fd_quic_ack_tx.h"
       6             : #include "fd_quic_retry.h"
       7             : #include "fd_quic_stream.h"
       8             : #include "fd_quic_conn_id.h"
       9             : #include "crypto/fd_quic_crypto_suites.h"
      10             : #include "templ/fd_quic_transport_params.h"
      11             : #include "fd_quic_pkt_meta.h"
      12             : 
      13      945690 : #define FD_QUIC_CONN_STATE_INVALID            0 /* dead object / freed */
      14      339663 : #define FD_QUIC_CONN_STATE_HANDSHAKE          1 /* currently doing handshaking with peer */
      15       85863 : #define FD_QUIC_CONN_STATE_HANDSHAKE_COMPLETE 2 /* handshake complete, confirming with peer */
      16    42726425 : #define FD_QUIC_CONN_STATE_ACTIVE             3 /* connection established - data may be transferred */
      17       42084 : #define FD_QUIC_CONN_STATE_PEER_CLOSE         4 /* peer requested close */
      18       15036 : #define FD_QUIC_CONN_STATE_ABORT              5 /* connection terminating due to error */
      19       43947 : #define FD_QUIC_CONN_STATE_CLOSE_PENDING      6 /* connection is closing */
      20    56646189 : #define FD_QUIC_CONN_STATE_DEAD               7 /* connection about to be freed */
      21             : 
      22             : enum {
      23             :   FD_QUIC_CONN_REASON_NO_ERROR                     = 0x00,    /* No error */
      24             :   FD_QUIC_CONN_REASON_INTERNAL_ERROR               = 0x01,    /* Implementation error */
      25             :   FD_QUIC_CONN_REASON_CONNECTION_REFUSED           = 0x02,    /* Server refuses a connection */
      26             :   FD_QUIC_CONN_REASON_FLOW_CONTROL_ERROR           = 0x03,    /* Flow control error */
      27             :   FD_QUIC_CONN_REASON_STREAM_LIMIT_ERROR           = 0x04,    /* Too many streams opened */
      28             :   FD_QUIC_CONN_REASON_STREAM_STATE_ERROR           = 0x05,    /* Frame received in invalid stream state */
      29             :   FD_QUIC_CONN_REASON_FINAL_SIZE_ERROR             = 0x06,    /* Change to final size */
      30             :   FD_QUIC_CONN_REASON_FRAME_ENCODING_ERROR         = 0x07,    /* Frame encoding error */
      31             :   FD_QUIC_CONN_REASON_TRANSPORT_PARAMETER_ERROR    = 0x08,    /* Error in transport parameters */
      32             :   FD_QUIC_CONN_REASON_CONNECTION_ID_LIMIT_ERROR    = 0x09,    /* Too many connection IDs received */
      33             :   FD_QUIC_CONN_REASON_PROTOCOL_VIOLATION           = 0x0a,    /* Generic protocol violation */
      34             :   FD_QUIC_CONN_REASON_INVALID_TOKEN                = 0x0b,    /* Invalid Token received */
      35             :   FD_QUIC_CONN_REASON_APPLICATION_ERROR            = 0x0c,    /* Application error */
      36             :   FD_QUIC_CONN_REASON_CRYPTO_BUFFER_EXCEEDED       = 0x0d,    /* CRYPTO data buffer overflowed */
      37             :   FD_QUIC_CONN_REASON_KEY_UPDATE_ERROR             = 0x0e,    /* Invalid packet protection update */
      38             :   FD_QUIC_CONN_REASON_AEAD_LIMIT_REACHED           = 0x0f,    /* Excessive use of packet protection keys */
      39             :   FD_QUIC_CONN_REASON_NO_VIABLE_PATH               = 0x10,    /* No viable network path exists */
      40             :   FD_QUIC_CONN_REASON_CRYPTO_BASE                  = 0x100,   /* 0x0100-0x01ff CRYPTO_ERROR TLS alert code*/
      41             :   /* QUIC permits the use of a generic code in place of a specific error code [...]
      42             :      such as handshake_failure (0x0128 in QUIC). */
      43             :   FD_QUIC_CONN_REASON_HANDSHAKE_FAILURE            = 0x128    /* Handshake failed. */
      44             : };
      45             : 
      46             : typedef struct fd_quic_conn       fd_quic_conn_t;
      47             : 
      48             : struct fd_quic_conn {
      49             :   uint               conn_idx;            /* connection index */
      50             :                                           /* connections are sized at runtime */
      51             :                                           /* storing the index avoids a division */
      52             : 
      53             :   fd_quic_t *        quic;
      54             :   void *             context;             /* user context */
      55             : 
      56             :   uint               server      : 1;     /* role from self POV: 0=client, 1=server */
      57             :   uint               established : 1;     /* used by clients to determine whether to
      58             :                                              switch the destination conn id used */
      59             :   uint               transport_params_set : 1;
      60             :   uint               called_conn_new : 1; /* whether we need to call conn_final on teardown */
      61             :   uint               visited : 1;         /* scratch bit, no strict definition */
      62             : 
      63             :   /* Service queue dlist membership.  All active conns (state not INVALID)
      64             :      are in a service queue, FD_QUIC_SVC_TYPE_WAIT by default.
      65             :      Free conns (svc_type==UINT_MAX) are members of a singly linked list
      66             :      (only src_next set) */
      67             :   uint               svc_type;  /* FD_QUIC_SVC_{...} or UINT_MAX */
      68             :   uint               svc_prev;
      69             :   uint               svc_next;
      70             :   ulong              svc_time;  /* service may be delayed until this timestamp */
      71             : 
      72             :   ulong              our_conn_id;
      73             : 
      74             :   /* Save original retry_source_connection_id
      75             :    * This is used by clients to compare against the retry_source_connection_id
      76             :    * in the transport parameters as specified in rfc 9000 7.3 */
      77             :   fd_quic_conn_id_t  retry_src_conn_id;
      78             : 
      79             :   /* Host network endpoint
      80             :      - for server, just a copy of config->net
      81             :      - for client, an allocated ephemeral UDP port */
      82             :   fd_quic_net_endpoint_t host;
      83             : 
      84             :   /* Peer network endpoints – have multiple connection ids and ip:port */
      85             :   /* TODO: footprint allows specifying conn_id_cnt but hardcoded limit used here */
      86             :   fd_quic_net_endpoint_t peer[1];
      87             :   fd_quic_conn_id_t      peer_cids[1]; /* FIXME support new/retire conn ID */
      88             : 
      89             :   ulong              local_conn_id;       /* FIXME: hack to locally identify conns */
      90             : 
      91             :   /* initial source connection id */
      92             :   fd_quic_conn_id_t  initial_source_conn_id;
      93             : 
      94             :   uint               tx_max_datagram_sz;  /* size of maximum datagram allowed by peer */
      95             : 
      96             :   /* handshake members */
      97             :   uint               handshake_complete  : 1; /* have we completed a successful handshake? */
      98             :   uint               handshake_done_send : 1; /* do we need to send handshake-done to peer? */
      99             :   uint               handshake_done_ackd : 1; /* was handshake_done ack'ed? */
     100             :   uint               hs_data_empty       : 1; /* has all hs_data been consumed? */
     101             :   fd_quic_tls_hs_t * tls_hs;
     102             : 
     103             :   /* expected handshake data offset - one per encryption level
     104             :      data received lower than this on a new packet is a protocol error
     105             :        duplicate packets should already have been dropped
     106             :      data received higher than this would be a gap
     107             :        ignore at present, assuming will be resent in order */
     108             :   ulong rx_crypto_offset[4]; /* expected handshake data (crypto) offset
     109             :                                    one per encryption level */
     110             : 
     111             :   /* amount of handshake data already sent from head of queue */
     112             :   ulong hs_sent_bytes[4];
     113             : 
     114             :   /* amount of handshake data ack'ed by peer counted from head of queue */
     115             :   ulong hs_ackd_bytes[4];
     116             : 
     117             :   /* secret members */
     118             :   fd_quic_crypto_secrets_t secrets;
     119             :   fd_quic_crypto_keys_t    keys[4][2];  /* a set of keys for each of the encoding levels, and for client/server */
     120             :   fd_quic_crypto_keys_t    new_keys[2]; /* a set of keys for use during key update */
     121             :   uint                     keys_avail;  /* bit set, LSB indexed by encryption level */
     122             :   uint                     key_phase;   /* current key phase - represents the current phase of the
     123             :                                            value of keys */
     124             :   uint                     key_phase_upd; /* set to 1 if we're undertaking a key update */
     125             : 
     126             :   fd_quic_stream_t         send_streams[1];      /* sentinel of list of streams needing action */
     127             :   fd_quic_stream_t         used_streams[1];      /* sentinel of list of used streams */
     128             :   /* invariant: an allocated stream must be in exactly one of the following lists:
     129             :      send_streams
     130             :      used_streams */
     131             : 
     132             :   /* stream id members */
     133             :   ulong next_stream_id[4];      /* next unused stream id by type - see rfc9000 2.1 */
     134             :                                 /* next_stream_id is used for streams coming from the stream pool */
     135             : 
     136             :   ulong rx_hi_stream_id;    /* highest RX stream ID sent by peer + 4 */
     137             :   ulong rx_sup_stream_id;   /* highest allowed RX stream ID + 4 */
     138             :   ulong tx_next_stream_id;  /* stream ID to be used for new stream */
     139             :   ulong tx_sup_stream_id;   /* highest allowed TX stream ID + 4 */
     140             : 
     141             :   ulong max_concur_streams[4];  /* user set concurrent max */
     142             : 
     143             :   /* stream id limits */
     144             :   /* limits->stream_cnt */
     145             :   /*   used to size stream_map, and provides an upper limit on the temporary limits */
     146             :   /*   on streams */
     147             : 
     148             :   /* max_concur_streams */
     149             :   /*   temporary limit on the number of streams */
     150             :   /*   currently only applies to peers */
     151             :   /*   may be adjusted via fd_quic_conn_set_max_streams */
     152             : 
     153             :   /* limits->initial_stream_cnt */
     154             :   /*   new connections attempt to assign initial_stream_cnt streams from the pool */
     155             :   /*   for peer initiated streams */
     156             :   /*   however many streams are assigned at this point becomes the limit imposed */
     157             :   /*   on the peer */
     158             : 
     159             :   /* peer initiated streams */
     160             :   /* the peer will create streams at will up to our imposed limit via max_streams */
     161             :   /* frames */
     162             :   /* max_streams frames are derived from changes to sup_stream_id */
     163             : 
     164             :   /* self initiated streams */
     165             :   /* we can create streams at will up to the peer imposed limit in peer_sup_stream_id */
     166             :   /* these streams also come from the stream pool, and so the size of the stream pool */
     167             :   /* also imposes a limit on self initiated streams */
     168             : 
     169             :   /* rfc9000:
     170             :        19.11 Note that these frames (and the corresponding transport parameters)
     171             :                do not describe the number of streams that can be opened concurrently.
     172             :         4.6  Only streams with a stream ID less than
     173             :                (max_streams * 4 + first_stream_id_of_type) can be opened
     174             :         2.1  Stream types:
     175             :              0x00 Client-Initiated, Bidirectional
     176             :              0x01 Server-Initiated, Bidirectional
     177             :              0x02 Client-Initiated, Unidirectional
     178             :              0x03 Server-Initiated, Unidirectional */
     179             : 
     180             :   ulong rx_max_streams_unidir_ackd; /* value of MAX_STREAMS acked for UNIDIR */
     181             : 
     182             :   fd_quic_stream_map_t *  stream_map;           /* map stream_id -> stream */
     183             : 
     184             :   /* packet number info
     185             :      each encryption level maps to a packet number space
     186             :      0-RTT and 1-RTT both map to APPLICATION
     187             :      pkt_number[j] represents the minimum acceptable packet number
     188             :        "expected packet number"
     189             :        packets with a number lower than this will be dropped */
     190             :   ulong exp_pkt_number[3]; /* different packet number spaces:
     191             :                                  INITIAL, HANDSHAKE and APPLICATION */
     192             :   ulong pkt_number[3];     /* tx packet number by pn space */
     193             :   ulong last_pkt_number[3]; /* last (highest) packet numer seen */
     194             : 
     195             :   ushort ipv4_id;           /* ipv4 id field */
     196             : 
     197             :   /* buffer to send next */
     198             :   /* rename tx_buf, since it's easy to confuse with stream->tx_buf */
     199             :   /* must be at least FD_QUIC_MAX_UDP_PAYLOAD_SZ */
     200             :   uchar   tx_buf[2048];
     201             :   uchar * tx_ptr; /* ptr to free space in tx_scratch */
     202             :   ulong   tx_sz;  /* sz remaining at ptr */
     203             : 
     204             :   uint state;
     205             :   uint reason;     /* quic reason for closing. see FD_QUIC_CONN_REASON_* */
     206             :   uint app_reason; /* application reason for closing */
     207             :   uint int_reason; /* internal reason */
     208             : 
     209             :   fd_quic_ack_gen_t ack_gen[1];
     210             :   ulong             unacked_sz;  /* Number of received stream frame payload bytes pending ACK */
     211             :                                  /* Resets to zero when conn is rescheduled or ACKs are sent */
     212             : 
     213             :   /* TODO find better name than pool */
     214             :   fd_quic_pkt_meta_pool_t pkt_meta_pool;
     215             :   fd_quic_pkt_meta_t *    pkt_meta_mem;    /* owns the memory */
     216             : 
     217             :   /* flow control */
     218             :   ulong                tx_max_data;        /* the limit on the number of bytes we are allowed
     219             :                                               to send to the peer across all streams */
     220             :                                            /* even if a bytes on a stream are not received,
     221             :                                               higher offsets received imply the usage of those bytes,
     222             :                                               and they count against the max */
     223             :   ulong                tx_tot_data;        /* total of all bytes received across all streams
     224             :                                               and including implied bytes */
     225             :   ulong                rx_max_data;        /* the limit on the number of bytes the peer is allowed to
     226             :                                               send to us */
     227             :   ulong                rx_tot_data;        /* total of all bytes received across all streams
     228             :                                               and including implied bytes */
     229             :   ulong                rx_max_data_ackd;   /* max max_data acked by peer */
     230             : 
     231             :   uint                 flags;
     232    47136203 : # define FD_QUIC_CONN_FLAGS_MAX_DATA           (1u<<0u)
     233       44517 : # define FD_QUIC_CONN_FLAGS_CLOSE_SENT         (1u<<1u)
     234     2285202 : # define FD_QUIC_CONN_FLAGS_MAX_STREAMS_UNIDIR (1u<<2u)
     235    20485666 : # define FD_QUIC_CONN_FLAGS_PING               (1u<<4u)
     236    18200464 : # define FD_QUIC_CONN_FLAGS_PING_SENT          (1u<<5u)
     237             : 
     238             :   uchar                spin_bit;                   /* spin bit used for latency measurements */
     239             : 
     240             :   /* max stream data per stream type */
     241             :   ulong                tx_initial_max_stream_data_uni;
     242             : 
     243             :   /* last tx packet num with max_data frame referring to this stream
     244             :      set to next_pkt_number to indicate a new max_data frame should be sent
     245             :      if we time out this packet (or possibly a later packet) we resend the frame
     246             :        and update this value */
     247             :   ulong                upd_pkt_number;
     248             : 
     249             :   /* current round-trip-time (FIXME this never updates) */
     250             :   ulong                rtt;
     251             : 
     252             :   /* highest peer encryption level */
     253             :   uchar                peer_enc_level;
     254             : 
     255             :   /* idle timeout arguments */
     256             :   ulong                idle_timeout;
     257             :   ulong                last_activity;
     258             : 
     259             :   /* rx_limit_pktnum is the newest inflight packet number in which
     260             :      the current rx_{sup_stream_id,max_data} values were sent to the
     261             :      peer.  (via MAX_STREAMS and MAX_DATA quota frames)
     262             :      FD_QUIC_PKT_NUM_UNUSED indicates that the peer ACked the latest
     263             :      quota update, and thus is in sync with the server.
     264             :      FD_QUIC_PKT_NUM_PENDING indicates that no packet with the current
     265             :      rx_{sup_stream_id,max_data} value was sent yet.  Will trigger a
     266             :      send attempt at the next fd_quic_conn_tx call. */
     267             :   ulong rx_limit_pktnum;
     268             : 
     269             :   ulong token_len;
     270             :   uchar token[ FD_QUIC_RETRY_MAX_TOKEN_SZ ];
     271             : };
     272             : 
     273             : FD_PROTOTYPES_BEGIN
     274             : 
     275             : /* returns the alignment requirement of fd_quic_conn_t */
     276             : FD_FN_CONST ulong
     277             : fd_quic_conn_align( void );
     278             : 
     279             : /* returns the footprint of the connection object for given limits */
     280             : FD_FN_PURE ulong
     281             : fd_quic_conn_footprint( fd_quic_limits_t const * );
     282             : 
     283             : /* called by fd_quic_new to initialize the connection objects
     284             :    used by fd_quic */
     285             : fd_quic_conn_t *
     286             : fd_quic_conn_new( void *                   mem,
     287             :                   fd_quic_t *              quic,
     288             :                   fd_quic_limits_t const * limits );
     289             : 
     290             : /* set the user-defined context value on the connection */
     291             : void
     292             : fd_quic_conn_set_context( fd_quic_conn_t * conn, void * context );
     293             : 
     294             : /* get the user-defined context value from a connection */
     295             : void *
     296             : fd_quic_conn_get_context( fd_quic_conn_t * conn );
     297             : 
     298             : FD_PROTOTYPES_END
     299             : 
     300             : #endif /* HEADER_fd_src_waltz_quic_fd_quic_conn_h */

Generated by: LCOV version 1.14