LCOV - code coverage report
Current view: top level - waltz/quic - fd_quic_pkt_meta.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 57 62 91.9 %
Date: 2025-11-09 04:41:14 Functions: 25 480 5.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_quic_fd_quic_pkt_meta_h
       2             : #define HEADER_fd_src_waltz_quic_fd_quic_pkt_meta_h
       3             : 
       4             : #include "fd_quic_common.h"
       5             : 
       6             : typedef struct fd_quic_pkt_meta         fd_quic_pkt_meta_t;
       7             : typedef struct fd_quic_pkt_meta_list    fd_quic_pkt_meta_list_t;
       8             : typedef struct fd_quic_pkt_meta_tracker fd_quic_pkt_meta_tracker_t;
       9             : 
      10             : /* fd_quic_pkt_meta_key used as key for tracking sent frames
      11             :  *
      12             :  * pkt_num:    packet number that carried this data
      13             :  * type:       type of data for retx (~frame type)
      14             :  * stream_id:  if stream type, the stream id
      15             :  */
      16             : 
      17             : union fd_quic_pkt_meta_key {
      18             :   struct {
      19             :     /* which frame type is recorded:
      20             :         FD_QUIC_PKT_META_TYPE_HS_DATA             handshake data
      21             :         FD_QUIC_PKT_META_TYPE_STREAM              stream data
      22             :         FD_QUIC_PKT_META_TYPE_HS_DONE             handshake-done frame
      23             :         FD_QUIC_PKT_META_TYPE_MAX_DATA            max_data frame
      24             :         FD_QUIC_PKT_META_TYPE_MAX_STREAMS_UNIDIR  max_streams frame (unidir)
      25             :         FD_QUIC_PKT_META_TYPE_CLOSE               close frame
      26             :         FD_QUIC_PKT_META_TYPE_PING                set to send a PING frame
      27             :     */
      28       49476 :     # define          FD_QUIC_PKT_META_TYPE_HS_DATA            (0)
      29    33551200 :     # define          FD_QUIC_PKT_META_TYPE_STREAM             (1)
      30       12321 :     # define          FD_QUIC_PKT_META_TYPE_HS_DONE            (2)
      31           0 :     # define          FD_QUIC_PKT_META_TYPE_MAX_DATA           (3)
      32           0 :     # define          FD_QUIC_PKT_META_TYPE_MAX_STREAMS_UNIDIR (4)
      33       12102 :     # define          FD_QUIC_PKT_META_TYPE_CLOSE              (5)
      34       12336 :     # define          FD_QUIC_PKT_META_TYPE_PING               (6)
      35             :     uchar type: 4;
      36             : 
      37             :     ulong pkt_num: 60;
      38             :     #define FD_QUIC_PKT_META_SET_TYPE(PKT_META_PTR, TYPE) \
      39    16827393 :       (PKT_META_PTR)->key.type = (uchar)((TYPE)&0x0f)
      40             : 
      41    18794474 :     #define FD_QUIC_PKT_META_PKT_NUM_MASK ( (1UL<<60) - 1 )
      42             :     #define FD_QUIC_PKT_META_SET_PKT_NUM(PKT_META_PTR, PKT_NUM) \
      43    17098538 :       (PKT_META_PTR)->key.pkt_num = (PKT_NUM)&FD_QUIC_PKT_META_PKT_NUM_MASK
      44             : 
      45             :     ulong stream_id;
      46             :   };
      47             :   ulong b[2];
      48             : };
      49             : typedef union fd_quic_pkt_meta_key fd_quic_pkt_meta_key_t;
      50             : FD_STATIC_ASSERT( sizeof(fd_quic_pkt_meta_key_t) == 16, fd_quic_pkt_meta_key_t );
      51             : 
      52             : union fd_quic_pkt_meta_value {
      53             :   ulong                scalar;
      54             :   fd_quic_range_t      range;
      55             : };
      56             : typedef union fd_quic_pkt_meta_value fd_quic_pkt_meta_value_t;
      57             : 
      58             : 
      59             : /* fd_quic_pkt_meta
      60             : 
      61             :    tracks the metadata of data sent to the peer
      62             :    used when acks arrive to determine what is being acked specifically */
      63             : struct fd_quic_pkt_meta {
      64             :   /* stores metadata about what was sent in the identified packet */
      65             :   fd_quic_pkt_meta_key_t   key;
      66             :   fd_quic_pkt_meta_value_t val;
      67             :   uchar                    enc_level: 2;
      68             :   uchar                    pn_space;    /* packet number space (derived from enc_level) */
      69             :   long                     tx_time;     /* transmit time */
      70             :   long                     expiry;      /* time pkt_meta expires... this is the time the
      71             :                                          ack is expected by */
      72             : 
      73             :   /* treap fields */
      74             :   ulong parent;
      75             :   ulong left;
      76             :   ulong right;
      77             :   ulong prio;
      78             :   ulong next;
      79             :   ulong prev;
      80             : };
      81             : typedef struct fd_quic_pkt_meta fd_quic_pkt_meta_t;
      82             : 
      83             : #define     POOL_NAME                 fd_quic_pkt_meta_pool
      84        6822 : #define     POOL_T                    fd_quic_pkt_meta_t
      85             : #include "../../util/tmpl/fd_pool.c"
      86             : 
      87             : /* if <pkt_nums,type> are diff, returns sign of difference
      88             :  *
      89             :  * else, returns sign of difference in stream_id */
      90             : static inline int
      91             : fd_quic_pkt_meta_cmp( const fd_quic_pkt_meta_key_t   q,
      92    34393163 :                       const fd_quic_pkt_meta_t     * e ) {
      93             :   /* branchless implementation of:
      94             :     diff = q.b[0] - e->key.b[0]
      95             :     if( diff )
      96             :       return diff
      97             :     return q.stream_id - e->key.stream_id */
      98    34393163 :   ulong q_b = q.b[0];
      99    34393163 :   ulong e_b = e->key.b[0];
     100    34393163 :   ulong q_s = q.stream_id;
     101    34393163 :   ulong e_s = e->key.stream_id;
     102             : 
     103    34393163 :   int pkt_num_type_cmp = -2*(q_b < e_b) + ((q_b > e_b)<<1);
     104    34393163 :   int stream_id_cmp    = -1*(q_s < e_s) + (q_s > e_s);
     105    34393163 :   return pkt_num_type_cmp + stream_id_cmp;
     106    34393163 : }
     107             : 
     108             : static inline int
     109             : fd_quic_pkt_meta_lt( const fd_quic_pkt_meta_t * e1,
     110    16539424 :                      const fd_quic_pkt_meta_t * e2 ) {
     111    16539424 :   ulong e1_b0 = e1->key.b[0];
     112    16539424 :   ulong e2_b0 = e2->key.b[0];
     113    16539424 :   return e1_b0 < e2_b0 || (e1_b0 == e2_b0 && e1->key.stream_id < e2->key.stream_id);
     114    16539424 : }
     115             : 
     116             : #define     TREAP_NAME                fd_quic_pkt_meta_treap
     117             : #define     TREAP_T                   fd_quic_pkt_meta_t
     118             : #define     TREAP_QUERY_T             fd_quic_pkt_meta_key_t
     119    34393154 : #define     TREAP_CMP(q,e)            fd_quic_pkt_meta_cmp( q, e )
     120    16539424 : #define     TREAP_LT(e0,e1)           fd_quic_pkt_meta_lt( e0, e1 )
     121             : #define     TREAP_OPTIMIZE_ITERATION  1
     122             : #include "../../util/tmpl/fd_treap.c"
     123             : 
     124             : /* begin aliasing to abstract data structure */
     125             : typedef fd_quic_pkt_meta_treap_t            fd_quic_pkt_meta_ds_t;
     126             : typedef fd_quic_pkt_meta_treap_fwd_iter_t   fd_quic_pkt_meta_ds_fwd_iter_t;
     127             : typedef fd_quic_pkt_meta_treap_rev_iter_t   fd_quic_pkt_meta_ds_rev_iter_t;
     128             : 
     129             : /* fd_quic_pkt_meta_ds_fwd_iter_init is equivalent of ds.begin()
     130             :    @arguments:
     131             :    - ds: pointer to the ds
     132             :    - pool: pointer to the backing pool
     133             :    @returns:
     134             :    - beginning iterator */
     135             : static inline fd_quic_pkt_meta_ds_fwd_iter_t
     136             : fd_quic_pkt_meta_ds_fwd_iter_init( fd_quic_pkt_meta_ds_t * ds,
     137    68689486 :                                    fd_quic_pkt_meta_t    * pool ) {
     138    68689486 :   return fd_quic_pkt_meta_treap_fwd_iter_init( ds, pool );
     139    68689486 : }
     140             : 
     141             : /* fd_quic_pkt_meta_ds_fwd_iter_ele returns pkt_meta* from iter
     142             :    @arguments:
     143             :    - iter: iterator
     144             :    - pool: pointer to the backing pool
     145             :    @returns:
     146             :    - pointer to pkt_meta */
     147             : static inline fd_quic_pkt_meta_t *
     148             : fd_quic_pkt_meta_ds_fwd_iter_ele( fd_quic_pkt_meta_ds_fwd_iter_t   iter,
     149    50407357 :                                   fd_quic_pkt_meta_t             * pool ) {
     150    50407357 :   return fd_quic_pkt_meta_treap_fwd_iter_ele( iter, pool );
     151    50407357 : }
     152             : 
     153             : /* fd_quic_pkt_meta_ds_fwd_iter_next is equivalent of iter++
     154             :    @arguments:
     155             :    - iter: iterator
     156             :    - pool: pointer to the backing pool
     157             :    @returns:
     158             :    - next iterator */
     159             : static inline fd_quic_pkt_meta_ds_fwd_iter_t
     160             : fd_quic_pkt_meta_ds_fwd_iter_next( fd_quic_pkt_meta_ds_fwd_iter_t   iter,
     161    33637753 :                                    fd_quic_pkt_meta_t             * pool ) {
     162    33637753 :   return fd_quic_pkt_meta_treap_fwd_iter_next( iter, pool );
     163    33637753 : }
     164             : 
     165             : /* fd_quic_pkt_meta_ds_fwd_iter_done returns boolean
     166             :   @arguments
     167             :   - iter: iterator
     168             :   @returns
     169             :   - non-zero if iterator marks end, 0 otherwise */
     170             : static inline int
     171   103451632 : fd_quic_pkt_meta_ds_fwd_iter_done( fd_quic_pkt_meta_ds_fwd_iter_t iter ) {
     172   103451632 :   return fd_quic_pkt_meta_treap_fwd_iter_done( iter );
     173   103451632 : }
     174             : 
     175             : /* fd_quic_pkt_meta_ds_rev_iter_init is equivalent of ds.end()
     176             :    @arguments:
     177             :    - ds: pointer to the ds
     178             :    - pool: pointer to the backing pool
     179             :    @returns:
     180             :    - beginning iterator */
     181             : static inline fd_quic_pkt_meta_ds_rev_iter_t
     182             : fd_quic_pkt_meta_ds_rev_iter_init( fd_quic_pkt_meta_ds_t * ds,
     183           0 :                                   fd_quic_pkt_meta_t    * pool ) {
     184           0 :   return fd_quic_pkt_meta_treap_rev_iter_init( ds, pool );
     185           0 : }
     186             : 
     187             : /* fd_quic_pkt_meta_ds_rev_iter_ele returns pkt_meta* from iter
     188             :    @arguments:
     189             :    - iter: iterator
     190             :    - pool: pointer to the backing pool
     191             :    @returns:
     192             :    - pointer to pkt_meta */
     193             : static inline fd_quic_pkt_meta_t *
     194             : fd_quic_pkt_meta_ds_rev_iter_ele( fd_quic_pkt_meta_ds_rev_iter_t   iter,
     195      792894 :                                   fd_quic_pkt_meta_t             * pool ) {
     196      792894 :   return fd_quic_pkt_meta_treap_rev_iter_ele( iter, pool );
     197      792894 : }
     198             : 
     199             : /* fd_quic_pkt_meta_ds_rev_iter_next is equivalent of iter--
     200             :   @arguments:
     201             :   - iter: iterator
     202             :   - pool: pointer to the backing pool
     203             :   @returns:
     204             :   - next iterator */
     205             : static inline fd_quic_pkt_meta_ds_fwd_iter_t
     206             : fd_quic_pkt_meta_ds_rev_iter_next( fd_quic_pkt_meta_ds_rev_iter_t   iter,
     207      792894 :                                   fd_quic_pkt_meta_t             * pool ) {
     208      792894 :   return fd_quic_pkt_meta_treap_rev_iter_next( iter, pool );
     209      792894 : }
     210             : 
     211             : /* fd_quic_pkt_meta_ds_rev_iter_done returns boolean
     212             :   @arguments
     213             :   - iter: iterator
     214             :   @returns
     215             :   - non-zero if iterator marks end, 0 otherwise */
     216             : static inline int
     217     1075442 : fd_quic_pkt_meta_ds_rev_iter_done( fd_quic_pkt_meta_ds_rev_iter_t iter ) {
     218     1075442 :   return fd_quic_pkt_meta_treap_rev_iter_done( iter );
     219     1075442 : }
     220             : 
     221             : /* fd_quic_pkt_meta_ds_idx_ge returns iterator pointing to first pkt_meta
     222             :   whose packet number is >= pkt_number
     223             :   @arguments
     224             :   - ds: pointer to the ds
     225             :   - pkt_number: pkt_number to search for
     226             :   - pool: pointer to the backing pool
     227             :   @returns
     228             :   - iterator to first pkt_meta with pkt number >= pkt_number */
     229             : static inline fd_quic_pkt_meta_ds_fwd_iter_t
     230             : fd_quic_pkt_meta_ds_idx_ge( fd_quic_pkt_meta_ds_t * ds,
     231             :                             ulong                   pkt_number,
     232      565420 :                             fd_quic_pkt_meta_t    * pool ) {
     233      565420 :   return fd_quic_pkt_meta_treap_idx_ge( ds,
     234      565420 :                                         (fd_quic_pkt_meta_key_t){
     235      565420 :                                           .pkt_num = pkt_number & FD_QUIC_PKT_META_PKT_NUM_MASK,
     236      565420 :                                           .type = 0,
     237      565420 :                                           .stream_id = 0},
     238      565420 :                                         pool );
     239      565420 : }
     240             : 
     241             : /* fd_quic_pkt_meta_ds_idx_le returns iterator pointing to first pkt_meta
     242             :   whose packet number is <= pkt_number. NOT just simple alias of treap_idx_le
     243             :   @arguments
     244             :   - ds: pointer to the ds
     245             :   - pkt_number: pkt_number to search for
     246             :   - pool: pointer to the backing pool
     247             :   @returns
     248             :   - iterator to last pkt_meta with pkt number <= pkt_number */
     249             : fd_quic_pkt_meta_ds_fwd_iter_t
     250             : fd_quic_pkt_meta_ds_idx_le( fd_quic_pkt_meta_ds_t * ds,
     251             :                             fd_quic_pkt_meta_t    * pool,
     252             :                             ulong                   pkt_number );
     253             : 
     254             : /* fd_quic_pkt_meta_ds_ele_cnt returns count of elements in ds */
     255             : static inline ulong
     256      106071 : fd_quic_pkt_meta_ds_ele_cnt( fd_quic_pkt_meta_ds_t * ds ) {
     257      106071 :   return fd_quic_pkt_meta_treap_ele_cnt( ds );
     258      106071 : }
     259             : 
     260             : /* end aliasing to abstract data structure */
     261             : 
     262             : struct fd_quic_pkt_meta_tracker {
     263             :   fd_quic_pkt_meta_ds_t       sent_pkt_metas[4];
     264             :   fd_quic_pkt_meta_t        * pool;
     265             : };
     266             : typedef struct fd_quic_pkt_meta_tracker fd_quic_pkt_meta_tracker_t;
     267             : 
     268             : /* fd_quic_pkt_meta_ds_init_pool does any data structure-particular setup
     269             :    on the entire pool at once. Useful for e.g. treap randomness
     270             :    @arguments:
     271             :    - pool: pointer pkt_meta pool
     272             :    - total_meta_cnt: total pool size */
     273             : void
     274             : fd_quic_pkt_meta_ds_init_pool( fd_quic_pkt_meta_t * pool,
     275             :                                ulong                total_meta_cnt );
     276             : 
     277             : /* fd_quic_pkt_meta_tracker_init initializes the metadata tracker for each enc level
     278             :   @arguments:
     279             :   - tracker: pointer to the tracker
     280             :   - total_meta_cnt: total number of max pkt_meta entries in this tracker
     281             :     (shared across all encoding levels)
     282             :   - pool: pointer to the backing pool
     283             :   @returns:
     284             :   - pointer to tracker if successful, NULL otherwise */
     285             : void *
     286             : fd_quic_pkt_meta_tracker_init( fd_quic_pkt_meta_tracker_t * tracker,
     287             :                                ulong                        total_meta_cnt,
     288             :                                fd_quic_pkt_meta_t         * pool );
     289             : 
     290             : /* fd_quic_pkt_meta_insert inserts a pkt_meta into the ds
     291             :   @arguments:
     292             :   - ds: pointer to the ds
     293             :   - pkt_meta: pointer to the pkt_meta to insert. This pkt_meta
     294             :       should have been acquired from the pool
     295             :   - pool: pointer to the backing pool */
     296             : void
     297             : fd_quic_pkt_meta_insert( fd_quic_pkt_meta_ds_t * ds,
     298             :                          fd_quic_pkt_meta_t    * pkt_meta,
     299             :                          fd_quic_pkt_meta_t    * pool );
     300             : 
     301             : /*
     302             :    remove all pkt_meta in the range [pkt_number_lo, pkt_number_hi]
     303             :    rm from treap and return to pool
     304             : */
     305             : /* fd_quic_pkt_meta_remove_range removes all pkt_meta in the range
     306             :   [pkt_number_lo, pkt_number_hi] from the ds and returns them to the pool.
     307             :   Any part of the range that's missing simply gets skipped
     308             :   @arguments:
     309             :   - ds: pointer to the ds
     310             :   - pool: pointer to the backing pool
     311             :   - pkt_number_lo: lower bound of the range
     312             :   - pkt_number_hi: upper bound of the range
     313             :   @returns:
     314             :   - number of pkt_meta removed */
     315             : ulong
     316             : fd_quic_pkt_meta_remove_range( fd_quic_pkt_meta_ds_t * ds,
     317             :                                fd_quic_pkt_meta_t    * pool,
     318             :                                ulong                   pkt_number_lo,
     319             :                                ulong                   pkt_number_hi );
     320             : 
     321             : /* fd_quic_pkt_meta_remove removes a single pkt_meta from the ds and returns it to the pool.
     322             :   @arguments:
     323             :   - ds: pointer to the ds
     324             :   - pool: pointer to the backing pool
     325             :   - pkt_meta: pointer to the pkt_meta to remove. Assumed non-null */
     326             : void
     327             : fd_quic_pkt_meta_remove( fd_quic_pkt_meta_ds_t * ds,
     328             :                          fd_quic_pkt_meta_t    * pool,
     329             :                          fd_quic_pkt_meta_t    * pkt_meta );
     330             : 
     331             : /* fd_quic_pkt_meta_min returns pointer to pkt_meta with smallest pkt_number in the ds
     332             :   @arguments:
     333             :   - ds: pointer to the ds
     334             :   - pool: pointer to the backing pool
     335             :   @returns:
     336             :   - pointer to pkt_meta with smallest pkt_number in the ds */
     337             : fd_quic_pkt_meta_t *
     338             : fd_quic_pkt_meta_min( fd_quic_pkt_meta_ds_t * ds,
     339             :                       fd_quic_pkt_meta_t    * pool );
     340             : 
     341             : /* fd_quic_pkt_meta_ds_clear clears all pkt_meta tracking for a given encryption level
     342             :   @arguments:
     343             :   - tracker: pointer to the pkt_meta tracker
     344             :   - enc_level: encryption level to clear */
     345             : void
     346             : fd_quic_pkt_meta_ds_clear( fd_quic_pkt_meta_tracker_t * tracker,
     347             :                            uint                         enc_level );
     348             : 
     349             : FD_PROTOTYPES_END
     350             : 
     351             : #endif // HEADER_fd_src_waltz_quic_fd_quic_pkt_meta_h

Generated by: LCOV version 1.14