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

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_quic_fd_quic_ack_tx_h
       2             : #define HEADER_fd_src_waltz_quic_fd_quic_ack_tx_h
       3             : 
       4             : /* fd_quic_ack_tx.h provides APIs for generating ACK packets.
       5             : 
       6             :    fd_quic generates delayed ACKs fire-and-forget style.
       7             :    Outgoing ACKs are artificially delayed by a pseudorandom delay.
       8             :    The max delay is known to the peer via the max_ack_delay transport
       9             :    parameter. */
      10             : 
      11             : #include "fd_quic_common.h"
      12             : 
      13             : #define FD_ACK_DEBUG(...)
      14             : //#define FD_ACK_DEBUG(...) __VA_ARGS__
      15             : 
      16             : /* FD_QUIC_ACK_QUEUE_CNT controls the number of disjoint ACK ranges
      17             :    that can be acknowledged between two calls to fd_quic_service.
      18             :    Higher values decrease retransmission rates in case of excessive
      19             :    reordering.  Must be a power of 2.
      20             : 
      21             :    Seq ack_queue_head-1 is always assumed to be valid. */
      22             : 
      23    61206630 : # define FD_QUIC_ACK_QUEUE_CNT (64)
      24             : 
      25             : /* fd_quic_ack_t is used to build an ACK frame.  It contains a
      26             :    contiguous range of packet numbers to ACK.  Whenever an fd_quic_t
      27             :    instance successfully processes a packet, it accumulates the packet
      28             :    number into an fd_quic_ack_t. */
      29             : 
      30             : struct __attribute__((aligned(16))) fd_quic_ack {
      31             :   fd_quic_range_t pkt_number;  /* Range of packet numbers being ACKed */
      32             :   ulong           ts;          /* timestamp of highest packet number */
      33             :   uchar           enc_level;   /* in [0,4) */
      34             :   /* FIXME enc_level should technically be pn_space instead */
      35             :   uchar           _pad[7];
      36             :   /* Tuned to 32 byte size */
      37             : };
      38             : 
      39             : typedef struct fd_quic_ack fd_quic_ack_t;
      40             : 
      41             : /* fd_quic_ack_gen_t records processed packet numbers and builds ACK
      42             :    frames.
      43             : 
      44             :    is_elicited==1 if at least one ACK-eliciting frame was received.
      45             :    No ACK frames will be generated unless this is the case.
      46             : 
      47             :    ack_instant==1 if an ACK for a packet must not be delayed.
      48             :    This is currently the case for initial and handshake-level packets.
      49             :    Note that is_elicited==1 takes priority.
      50             : 
      51             :    The ack_queue ring caches the last generated ACK frames.  It uses
      52             :    sequence numbers that wrap around in [0,2^32).  queue_tail is the seq
      53             :    no of the oldest unsent ACK frame.  queue_head is the next unused
      54             :    seq.  Note that packet number ranges in this ring have no ordering
      55             :    requirements.
      56             : 
      57             :    All fd_quic_ack_t in the ack_queue array are initialized, even when
      58             :    they are not present in the ring.  If the ring is empty (head==tail),
      59             :    may peek the element at seq queue_head-1. */
      60             : 
      61             : struct __attribute__((aligned(16))) fd_quic_ack_gen {
      62             : 
      63             :   fd_quic_ack_t  queue[FD_QUIC_ACK_QUEUE_CNT];
      64             :   uint           head;
      65             :   uint           tail;
      66             : 
      67             :   uchar          is_elicited;
      68             : 
      69             : };
      70             : 
      71             : typedef struct fd_quic_ack_gen fd_quic_ack_gen_t;
      72             : 
      73             : FD_PROTOTYPES_BEGIN
      74             : 
      75             : /* fd_quic_ack_gen_init initializes the fd_quic_ack_gen_t instance. */
      76             : 
      77             : static inline fd_quic_ack_gen_t *
      78      314481 : fd_quic_ack_gen_init( fd_quic_ack_gen_t * ack_gen ) {
      79      314481 :   memset( ack_gen, 0, sizeof(fd_quic_ack_gen_t) );
      80      314481 :   return ack_gen;
      81      314481 : }
      82             : 
      83             : /* fd_quic_ack_pkt queues a processed packet for acknowledgement. */
      84             : 
      85             : void
      86             : fd_quic_ack_pkt( fd_quic_ack_gen_t * gen,
      87             :                  ulong               pkt_number,
      88             :                  uint                enc_level,
      89             :                  ulong               now );
      90             : 
      91             : /* fd_quic_ack_queue_ele returns the ack_queue element indexed by a
      92             :    sequence number. */
      93             : 
      94             : FD_FN_PURE static inline fd_quic_ack_t *
      95             : fd_quic_ack_queue_ele( fd_quic_ack_gen_t * ack_gen,
      96    60888151 :                        uint                idx ) {
      97    60888151 :   return ack_gen->queue + (idx & (FD_QUIC_ACK_QUEUE_CNT-1));
      98    60888151 : }
      99             : 
     100             : /* fd_quic_ack_gen_abandon_enc_level removes queued ACKs with an
     101             :    encryption level equal or lower than enc_level. */
     102             : 
     103             : void
     104             : fd_quic_ack_gen_abandon_enc_level( fd_quic_ack_gen_t * ack_gen,
     105             :                                    uint                enc_level );
     106             : 
     107             : /* fd_quic_gen_ack_frames writes ACK frames to the memory region
     108             :    [payload_ptr,payload_end).  Returns a pointer one past the last byte
     109             :    written (in [payload_ptr,payload_end]). */
     110             : 
     111             : uchar *
     112             : fd_quic_gen_ack_frames( fd_quic_ack_gen_t * gen,
     113             :                         uchar *             payload_ptr,
     114             :                         uchar *             payload_end,
     115             :                         uint                enc_level,
     116             :                         ulong               now );
     117             : 
     118             : FD_PROTOTYPES_END
     119             : 
     120             : #endif /* HEADER_fd_src_waltz_quic_fd_quic_ack_tx_h */

Generated by: LCOV version 1.14