LCOV - code coverage report
Current view: top level - waltz/quic/tests - fd_quic_sandbox.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 235 263 89.4 %
Date: 2025-09-20 04:42:25 Functions: 12 12 100.0 %

          Line data    Source code
       1             : #include "fd_quic_sandbox.h"
       2             : #include "../fd_quic_private.h"
       3             : #include "../templ/fd_quic_parse_util.h"
       4             : 
       5             : /* fd_quic_sandbox_capture_pkt captures a single outgoing packet sent by
       6             :    fd_quic. */
       7             : 
       8             : static void
       9             : fd_quic_sandbox_capture_pkt( fd_quic_sandbox_t *       sandbox,
      10     1811412 :                              fd_aio_pkt_info_t const * pkt ) {
      11             : 
      12     1811412 :   ulong            seq    = sandbox->pkt_seq_w;
      13     1811412 :   fd_frag_meta_t * mcache = sandbox->pkt_mcache;
      14     1811412 :   void *           dcache = sandbox->pkt_dcache;
      15     1811412 :   ulong            mtu    = sandbox->pkt_mtu;
      16     1811412 :   ulong            chunk  = sandbox->pkt_chunk;
      17     1811412 :   ulong            chunk0 = fd_dcache_compact_chunk0( sandbox, dcache );
      18     1811412 :   ulong            wmark  = fd_dcache_compact_wmark ( sandbox, dcache, mtu );
      19     1811412 :   ulong            depth  = fd_mcache_depth( mcache );
      20     1811412 :   ulong            sz     = pkt->buf_sz;
      21     1811412 :   uchar *          data   = fd_chunk_to_laddr( sandbox, chunk );
      22     1811412 :   ulong            ctl    = fd_frag_meta_ctl( /* orig */ 0, /* som */ 1, /* eom */ 1, /* err */ 0 );
      23     1811412 :   long             ts     = sandbox->wallclock;
      24             : 
      25     1811412 :   fd_memcpy( data, pkt->buf, sz );
      26     1811412 :   ulong tscomp = fd_frag_meta_ts_comp( ts );
      27     1811412 :   fd_mcache_publish( mcache, depth, seq, 0UL, chunk, sz, ctl, tscomp, tscomp );
      28             : 
      29     1811412 :   sandbox->pkt_seq_w = fd_seq_inc( seq, 1UL );
      30     1811412 :   sandbox->pkt_chunk = fd_dcache_compact_next( chunk, pkt->buf_sz, chunk0, wmark );
      31     1811412 : }
      32             : 
      33             : /* fd_quic_sandbox_aio_send implements fd_aio_send_func_t.  Called by
      34             :    the sandbox fd_quic to capture response packets into the sandbox
      35             :    capture ring. */
      36             : 
      37             : static int
      38             : fd_quic_sandbox_aio_send( void *                    ctx,
      39             :                           fd_aio_pkt_info_t const * batch,
      40             :                           ulong                     batch_cnt,
      41             :                           ulong *                   opt_batch_idx,
      42     1811412 :                           int                       flush ) {
      43             : 
      44     1811412 :   fd_quic_sandbox_t * sandbox = (fd_quic_sandbox_t *)ctx;
      45             : 
      46     3622824 :   for( ulong j=0UL; j<batch_cnt; j++ ) {
      47     1811412 :     fd_quic_sandbox_capture_pkt( sandbox, batch + j );
      48     1811412 :   }
      49             : 
      50     1811412 :   ulong _batch_idx[1];
      51     1811412 :   opt_batch_idx = opt_batch_idx ? opt_batch_idx : _batch_idx;
      52     1811412 :   *opt_batch_idx = batch_cnt;
      53             : 
      54     1811412 :   (void)flush;
      55     1811412 :   return FD_AIO_SUCCESS;
      56     1811412 : }
      57             : 
      58             : fd_frag_meta_t const *
      59           6 : fd_quic_sandbox_next_packet( fd_quic_sandbox_t * sandbox ) {
      60           6 :   fd_frag_meta_t * mcache = sandbox->pkt_mcache;
      61             : 
      62           6 :   ulong depth = fd_mcache_depth( mcache );
      63           6 :   ulong seq   = sandbox->pkt_seq_r;
      64           6 :   ulong mline = fd_mcache_line_idx( seq, depth );
      65             : 
      66           6 :   fd_frag_meta_t * frag = mcache + mline;
      67           6 :   if( FD_UNLIKELY( fd_seq_lt( frag->seq, seq ) ) ) return NULL;
      68           6 :   if( FD_UNLIKELY( fd_seq_gt( frag->seq, seq ) ) ) {
      69             :     /* Occurs if the fd_quic published 'depth' packets in succession
      70             :        without any reads via this function. */
      71           0 :     FD_LOG_WARNING(( "overrun detected, some captured packets were lost" ));
      72           0 :     seq = frag->seq;
      73           0 :   }
      74             : 
      75           6 :   sandbox->pkt_seq_r = fd_seq_inc( seq, 1UL );
      76             : 
      77           6 :   return frag;
      78           6 : }
      79             : 
      80             : uchar const fd_quic_sandbox_self_ed25519_keypair[64] =
      81             :   { /* private key */
      82             :     0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
      83             :     0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
      84             :     0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
      85             :     0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
      86             :     /* public key */
      87             :     0xdb, 0x99, 0x5f, 0xe2, 0x51, 0x69, 0xd1, 0x41,
      88             :     0xca, 0xb9, 0xbb, 0xba, 0x92, 0xba, 0xa0, 0x1f,
      89             :     0x9f, 0x2e, 0x1e, 0xce, 0x7d, 0xf4, 0xcb, 0x2a,
      90             :     0xc0, 0x51, 0x90, 0xf3, 0x7f, 0xcc, 0x1f, 0x9d };
      91             : 
      92             : 
      93             : uchar const fd_quic_sandbox_peer_ed25519_keypair[64] =
      94             :   { /* private key */
      95             :     0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
      96             :     0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
      97             :     0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
      98             :     0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
      99             :     /* public key */
     100             :     0x21, 0x52, 0xf8, 0xd1, 0x9b, 0x79, 0x1d, 0x24,
     101             :     0x45, 0x32, 0x42, 0xe1, 0x5f, 0x2e, 0xab, 0x6c,
     102             :     0xb7, 0xcf, 0xfa, 0x7b, 0x6a, 0x5e, 0xd3, 0x00,
     103             :     0x97, 0x96, 0x0e, 0x06, 0x98, 0x81, 0xdb, 0x12 };
     104             : 
     105             : uchar const fd_quic_sandbox_aes128_key[16] =
     106             :   { 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
     107             :     0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43 };
     108             : 
     109             : uchar const fd_quic_sandbox_aes128_iv[12] =
     110             :   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     111             :     0x00, 0x00, 0x00, 0x00 };
     112             : 
     113             : ulong
     114          30 : fd_quic_sandbox_align( void ) {
     115          30 :   return fd_ulong_max( fd_ulong_max( fd_ulong_max( fd_ulong_max(
     116          30 :       alignof(fd_quic_sandbox_t),
     117          30 :       fd_quic_align() ),
     118          30 :       fd_mcache_align() ),
     119          30 :       fd_dcache_align() ),
     120          30 :       FD_CHUNK_ALIGN );
     121          30 : }
     122             : 
     123             : ulong
     124             : fd_quic_sandbox_footprint( fd_quic_limits_t const * quic_limits,
     125             :                            ulong                    pkt_cnt,
     126          12 :                            ulong                    mtu ) {
     127             : 
     128          12 :   ulong root_align = fd_quic_sandbox_align();
     129          12 :   ulong quic_fp    = fd_quic_footprint( quic_limits );
     130          12 :   ulong mcache_fp  = fd_mcache_footprint( pkt_cnt, 0UL );
     131          12 :   ulong dcache_fp  = fd_dcache_footprint( fd_dcache_req_data_sz( mtu, pkt_cnt, 1UL, 1 ), 0UL );
     132             : 
     133          12 :   if( FD_UNLIKELY( !quic_fp   ) ) return 0UL;
     134          12 :   if( FD_UNLIKELY( !mcache_fp ) ) return 0UL;
     135          12 :   if( FD_UNLIKELY( !dcache_fp ) ) return 0UL;
     136             : 
     137          12 :   ulong l = FD_LAYOUT_INIT;
     138          12 :   l = FD_LAYOUT_APPEND( l, root_align,        sizeof(fd_quic_sandbox_t) );
     139          12 :   l = FD_LAYOUT_APPEND( l, fd_quic_align(),   quic_fp                   );
     140          12 :   l = FD_LAYOUT_APPEND( l, fd_mcache_align(), mcache_fp                 );
     141          12 :   l = FD_LAYOUT_APPEND( l, fd_dcache_align(), dcache_fp                 );
     142          12 :   return FD_LAYOUT_FINI( l, root_align );
     143          12 : }
     144             : 
     145             : fd_quic_sandbox_t *
     146             : fd_quic_sandbox_new( void *                   mem,
     147             :                      fd_quic_limits_t const * quic_limits,
     148             :                      ulong                    pkt_cnt,
     149           6 :                      ulong                    mtu ) {
     150             : 
     151           6 :   if( FD_UNLIKELY( !mem ) ) {
     152           0 :     FD_LOG_WARNING(( "NULL mem" ));
     153           0 :     return NULL;
     154           0 :   }
     155             : 
     156           6 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_quic_sandbox_align() ) ) ) {
     157           0 :     FD_LOG_WARNING(( "misaligned mem" ));
     158           0 :     return NULL;
     159           0 :   }
     160             : 
     161           6 :   ulong fp = fd_quic_sandbox_footprint( quic_limits, pkt_cnt, mtu );
     162           6 :   if( FD_UNLIKELY( !fp ) ) {
     163           0 :     FD_LOG_WARNING(( "invalid params" ));
     164           0 :     return NULL;
     165           0 :   }
     166             : 
     167           6 :   ulong root_align     = fd_quic_sandbox_align();
     168           6 :   ulong quic_fp        = fd_quic_footprint( quic_limits );
     169           6 :   ulong mcache_fp      = fd_mcache_footprint( pkt_cnt, 0UL );
     170           6 :   ulong dcache_data_sz = fd_dcache_req_data_sz( mtu, pkt_cnt, 1UL, 1 );
     171           6 :   ulong dcache_fp      = fd_dcache_footprint( dcache_data_sz, 0UL );
     172             : 
     173           6 :   FD_SCRATCH_ALLOC_INIT( l, mem );
     174           6 :   fd_quic_sandbox_t * sandbox    = FD_SCRATCH_ALLOC_APPEND( l, root_align,        sizeof(fd_quic_sandbox_t) );
     175           6 :   void *              quic_mem   = FD_SCRATCH_ALLOC_APPEND( l, fd_quic_align(),   quic_fp                   );
     176           6 :   void *              mcache_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_mcache_align(), mcache_fp                 );
     177           6 :   void *              dcache_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_dcache_align(), dcache_fp                 );
     178           6 :   FD_SCRATCH_ALLOC_FINI( l, root_align );
     179             : 
     180           6 :   ulong seq0 = 0UL;  /* the first packet in the capture always has sequence number 0 */
     181             : 
     182           6 :   *sandbox = (fd_quic_sandbox_t) {
     183           6 :     .quic       = fd_quic_join  ( fd_quic_new( quic_mem, quic_limits ) ),
     184           6 :     .pkt_mcache = fd_mcache_join( fd_mcache_new( mcache_mem, pkt_cnt, 0UL, seq0 ) ),
     185           6 :     .pkt_dcache = fd_dcache_join( fd_dcache_new( dcache_mem, dcache_data_sz, 0UL ) ),
     186           6 :     .pkt_seq_r  = seq0,
     187           6 :     .pkt_mtu    = mtu
     188           6 :   };
     189           6 :   void * shmlog = (void *)( (ulong)sandbox->quic + sandbox->quic->layout.log_off );
     190           6 :   if( FD_UNLIKELY( !fd_quic_log_rx_join( sandbox->log_rx, shmlog ) ) ) {
     191           0 :     FD_LOG_CRIT(( "Failed to join the log of a newly created quic" ));
     192           0 :   }
     193             : 
     194           6 :   FD_COMPILER_MFENCE();
     195           6 :   sandbox->magic = FD_QUIC_SANDBOX_MAGIC;
     196           6 :   FD_COMPILER_MFENCE();
     197             : 
     198           6 :   return sandbox;
     199           6 : }
     200             : 
     201             : fd_quic_sandbox_t *
     202             : fd_quic_sandbox_init( fd_quic_sandbox_t * sandbox,
     203          42 :                       int                 role ) {
     204             : 
     205          42 :   fd_quic_t *        quic     = sandbox->quic;
     206          42 :   fd_quic_config_t * quic_cfg = &quic->config;
     207             : 
     208          42 :   quic_cfg->role                  = role;
     209          42 :   quic_cfg->idle_timeout          = FD_QUIC_SANDBOX_IDLE_TIMEOUT;
     210          42 :   quic_cfg->initial_rx_max_stream_data = 512UL; /* arbitrary */
     211          42 :   memcpy( quic_cfg->identity_public_key, fd_quic_sandbox_self_ed25519_keypair + 32, 32 );
     212          42 :   memset( &quic->metrics, 0, sizeof(fd_quic_metrics_t) );
     213             : 
     214          42 :   fd_aio_t aio_tx = {
     215          42 :     .send_func = fd_quic_sandbox_aio_send,
     216          42 :     .ctx       = sandbox
     217          42 :   };
     218          42 :   fd_quic_set_aio_net_tx( quic, &aio_tx );
     219             : 
     220          42 :   if( FD_UNLIKELY( !fd_quic_init( quic ) ) ) {
     221           0 :     FD_LOG_WARNING(( "fd_quic_init failed" ));
     222           0 :     return NULL;
     223           0 :   }
     224             : 
     225             :   /* Verify that the conn state counts start correct */
     226          42 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_INVALID ] == quic->limits.conn_cnt );
     227          42 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_HANDSHAKE ] == 0 );
     228          42 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_HANDSHAKE_COMPLETE ] == 0 );
     229          42 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_ACTIVE ] == 0 );
     230          42 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_PEER_CLOSE ] == 0 );
     231          42 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_ABORT ] == 0 );
     232          42 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_CLOSE_PENDING ] == 0 );
     233          42 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_DEAD ] == 0 );
     234             : 
     235          42 :   fd_quic_state_t * state = fd_quic_get_state( quic );
     236          42 :   state->now = 1L;
     237          42 :   sandbox->wallclock = 1L;
     238          42 :   sandbox->pkt_seq_r = 0UL;
     239          42 :   sandbox->pkt_seq_w = 0UL;
     240          42 :   sandbox->pkt_mcache[0].seq = ULONG_MAX;  /* mark first entry as unpublished */
     241          42 :   sandbox->pkt_chunk = fd_dcache_compact_chunk0( sandbox, sandbox->pkt_dcache );
     242             : 
     243             :   /* skip ahead the log seq no */
     244          42 :   fd_quic_log_tx_t * log_tx = state->log_tx;
     245          42 :   log_tx->seq += 4093; /* prime */
     246             : 
     247          42 :   return sandbox;
     248          42 : }
     249             : 
     250             : void *
     251           6 : fd_quic_sandbox_delete( fd_quic_sandbox_t * mem ) {
     252             : 
     253           6 :   if( FD_UNLIKELY( !mem ) ) {
     254           0 :     FD_LOG_WARNING(( "NULL mem" ));
     255           0 :     return NULL;
     256           0 :   }
     257             : 
     258           6 :   fd_quic_sandbox_t * sandbox = (fd_quic_sandbox_t *)mem;
     259           6 :   if( FD_UNLIKELY( sandbox->magic != FD_QUIC_SANDBOX_MAGIC ) ) {
     260           0 :     FD_LOG_WARNING(( "invalid magic" ));
     261           0 :     return NULL;
     262           0 :   }
     263             : 
     264           6 :   FD_COMPILER_MFENCE();
     265           6 :   sandbox->magic = 0UL;
     266           6 :   FD_COMPILER_MFENCE();
     267             : 
     268           6 :   fd_quic_delete  ( fd_quic_leave  ( sandbox->quic       ) );
     269           6 :   fd_mcache_delete( fd_mcache_leave( sandbox->pkt_mcache ) );
     270           6 :   fd_dcache_delete( fd_dcache_leave( sandbox->pkt_dcache ) );
     271             : 
     272           6 :   return mem;
     273           6 : }
     274             : 
     275             : fd_quic_conn_t *
     276             : fd_quic_sandbox_new_conn_established( fd_quic_sandbox_t * sandbox,
     277      300057 :                                       fd_rng_t *          rng ) {
     278             : 
     279      300057 :   fd_quic_t * quic = sandbox->quic;
     280             : 
     281             :   /* fd_quic_t conn IDs are always 8 bytes */
     282      300057 :   ulong             our_conn_id_u64 = fd_rng_ulong( rng );
     283             : 
     284             :   /* the peer may choose a conn ID size 1 to 16 bytes
     285             :      For now, pick 8 bytes too */
     286      300057 :   ulong             peer_conn_id_u64 = fd_rng_ulong( rng );
     287      300057 :   fd_quic_conn_id_t peer_conn_id     = fd_quic_conn_id_new( &peer_conn_id_u64, 8UL );
     288             : 
     289      300057 :   fd_quic_conn_t * conn = fd_quic_conn_create(
     290      300057 :       /* quic         */ quic,
     291      300057 :       /* our_conn_id  */ our_conn_id_u64,
     292      300057 :       /* peer_conn_id */ &peer_conn_id,
     293      300057 :       /* dst_ip_addr  */ FD_QUIC_SANDBOX_PEER_IP4,
     294      300057 :       /* dst_udp_addr */ FD_QUIC_SANDBOX_PEER_PORT,
     295      300057 :       /* src_ip_addr  */ FD_QUIC_SANDBOX_SELF_IP4,
     296      300057 :       /* src_udp_addr */ FD_QUIC_SANDBOX_SELF_PORT,
     297      300057 :       /* server       */ quic->config.role == FD_QUIC_ROLE_SERVER );
     298      300057 :   if( FD_UNLIKELY( !conn ) ) {
     299           0 :     FD_LOG_WARNING(( "fd_quic_conn_create failed" ));
     300           0 :     return NULL;
     301           0 :   }
     302             : 
     303      300057 :   conn->state       = FD_QUIC_CONN_STATE_ACTIVE;
     304      300057 :   conn->established = 1;
     305             : 
     306             :   /* Mock a completed handshake */
     307      300057 :   conn->handshake_complete = 1;
     308      300057 :   conn->peer_enc_level     = fd_quic_enc_level_appdata_id;
     309      300057 :   conn->keys_avail         = 1U<<fd_quic_enc_level_appdata_id;
     310             : 
     311      300057 :   conn->idle_timeout_ns    = FD_QUIC_SANDBOX_IDLE_TIMEOUT;
     312      300057 :   conn->last_activity      = sandbox->wallclock;
     313             : 
     314             :   /* Reset flow control limits */
     315      300057 :   conn->tx_max_data           = 0UL;
     316      300057 :   conn->tx_tot_data           = 0UL;
     317      300057 :   conn->srx->rx_max_data      = 0UL;
     318      300057 :   conn->srx->rx_tot_data      = 0UL;
     319      300057 :   conn->srx->rx_max_data_ackd = 0UL;
     320      300057 :   conn->tx_initial_max_stream_data_uni = 0UL;
     321             : 
     322             :   /* TODO set a realistic packet number */
     323             : 
     324      300057 :   return conn;
     325      300057 : }
     326             : 
     327             : void
     328             : fd_quic_sandbox_send_frame( fd_quic_sandbox_t * sandbox,
     329             :                             fd_quic_conn_t *    conn,
     330             :                             fd_quic_pkt_t *     pkt_meta,
     331             :                             uchar const *       frame_ptr,
     332    29825353 :                             ulong               frame_sz ) {
     333             : 
     334             :   /* TODO consider crafting a real app packet instead of bypassing
     335             :           packet processing checks */
     336             : 
     337    29825353 :   fd_quic_t * quic = sandbox->quic;
     338             : 
     339             :   /* set pkt_type to FD_QUIC_PKT_TYPE_ONE_RTT as it allows all
     340             :    * frame types */
     341    29825353 :   uint pkt_type = FD_QUIC_PKT_TYPE_ONE_RTT;
     342             : 
     343    29825353 :   ulong rc = fd_quic_handle_v1_frame( quic, conn, pkt_meta, pkt_type, frame_ptr, frame_sz );
     344    29825353 :   if( FD_UNLIKELY( rc==FD_QUIC_PARSE_FAIL ) ) return;
     345    29825344 :   if( FD_UNLIKELY( rc==0UL || rc>frame_sz ) ) {
     346           0 :     FD_LOG_CRIT(( "Invalid fd_quic_handle_v1_frame return value (rc=%#lx frame_sz=%#lx)", rc, frame_sz ));
     347           0 :   }
     348             : 
     349    29825344 : }
     350             : 
     351             : void
     352             : fd_quic_sandbox_send_lone_frame( fd_quic_sandbox_t * sandbox,
     353             :                                  fd_quic_conn_t *    conn,
     354             :                                  uchar const *       frame,
     355    29825350 :                                  ulong               frame_sz ) {
     356             : 
     357    29825350 :   FD_TEST( frame_sz <= sandbox->pkt_mtu );
     358             : 
     359    29825350 :   ulong pkt_num = conn->exp_pkt_number[2]++;
     360             : 
     361    29825350 :   ulong quic_pkt_sz = frame_sz;  /* TODO mock some QUIC packetization overhead */
     362             : 
     363    29825350 :   fd_quic_pkt_t pkt_meta = {
     364    29825350 :     .ip4 = {{
     365    29825350 :       .verihl       = FD_IP4_VERIHL(4,5),
     366    29825350 :       .net_tot_len  = (ushort)( 20 + 8 + quic_pkt_sz ),
     367    29825350 :       .net_frag_off = 0x4000u, /* don't fragment */
     368    29825350 :       .ttl          = 64,
     369    29825350 :       .protocol     = FD_IP4_HDR_PROTOCOL_UDP,
     370    29825350 :     }},
     371    29825350 :     .udp = {{
     372    29825350 :       .net_sport = FD_QUIC_SANDBOX_PEER_PORT,
     373    29825350 :       .net_dport = FD_QUIC_SANDBOX_SELF_PORT,
     374    29825350 :       .net_len   = (ushort)( 8 + quic_pkt_sz ),
     375    29825350 :     }},
     376    29825350 :     .pkt_number = pkt_num,
     377    29825350 :     .rcv_time   = sandbox->wallclock,
     378    29825350 :     .enc_level  = fd_quic_enc_level_appdata_id,
     379    29825350 :   };
     380             : 
     381    29825350 :   fd_quic_sandbox_send_frame( sandbox, conn, &pkt_meta, frame, frame_sz );
     382             : 
     383    29825350 :   fd_quic_lazy_ack_pkt( sandbox->quic, conn, &pkt_meta );
     384             : 
     385             :   /* Synchronize log seq[0] from tx to rx */
     386    29825350 :   fd_quic_log_tx_seq_update( fd_quic_get_state( sandbox->quic )->log_tx );
     387    29825350 : }
     388             : 
     389             : void
     390             : fd_quic_sandbox_send_ping_pkt( fd_quic_sandbox_t * sandbox,
     391             :                                fd_quic_conn_t *    conn,
     392         210 :                                ulong               pktnum ) {
     393             : 
     394         210 :   uchar pkt_buf[ 256 ];
     395         210 :   pkt_buf[0] = fd_quic_one_rtt_h0( /* spin */         0,
     396         210 :                                    /* key_phase */    !!conn->key_phase,
     397         210 :                                    /* pktnum_len-1 */ 3 );
     398         210 :   memcpy( pkt_buf+1, &conn->our_conn_id, FD_QUIC_CONN_ID_SZ );
     399         210 :   uint pktnum_comp = fd_uint_bswap( (uint)( pktnum & UINT_MAX ) );
     400         210 :   memcpy( pkt_buf+9, &pktnum_comp, 4 );
     401         210 :   pkt_buf[13] = 0x01;  /* PING frame */
     402         210 :   memset( pkt_buf+14, 0, 18UL );
     403             : 
     404         210 :   fd_quic_crypto_keys_t * keys = &conn->keys[fd_quic_enc_level_appdata_id][0];
     405         210 :   ulong out_sz = 48UL;
     406         210 :   int crypt_res = fd_quic_crypto_encrypt( pkt_buf, &out_sz, pkt_buf, 13UL, pkt_buf+13, 19UL, keys, keys, pktnum );
     407         210 :   FD_TEST( crypt_res==FD_QUIC_SUCCESS );
     408             : 
     409         210 :   fd_quic_pkt_t pkt = {
     410         210 :     .ip4 = {{
     411         210 :       .verihl       = FD_IP4_VERIHL(4,5),
     412         210 :       .net_tot_len  = 28,
     413         210 :       .net_frag_off = 0x4000u, /* don't fragment */
     414         210 :       .ttl          = 64,
     415         210 :       .protocol     = FD_IP4_HDR_PROTOCOL_UDP,
     416         210 :     }},
     417         210 :     .udp = {{
     418         210 :       .net_sport = FD_QUIC_SANDBOX_PEER_PORT,
     419         210 :       .net_dport = FD_QUIC_SANDBOX_SELF_PORT,
     420         210 :       .net_len   = 8,
     421         210 :     }},
     422         210 :     .pkt_number = pktnum,
     423         210 :     .rcv_time   = sandbox->wallclock,
     424         210 :     .enc_level  = fd_quic_enc_level_appdata_id,
     425         210 :   };
     426             : 
     427         210 :   fd_quic_process_quic_packet_v1( sandbox->quic, &pkt, pkt_buf, out_sz );
     428         210 : }

Generated by: LCOV version 1.14