LCOV - code coverage report
Current view: top level - waltz/quic/tests - fd_quic_sandbox.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 244 272 89.7 %
Date: 2026-09-17 04:28:31 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         210 :                              fd_aio_pkt_info_t const * pkt ) {
      11             : 
      12         210 :   ulong            seq    = sandbox->pkt_seq_w;
      13         210 :   fd_frag_meta_t * mcache = sandbox->pkt_mcache;
      14         210 :   void *           dcache = sandbox->pkt_dcache;
      15         210 :   ulong            mtu    = sandbox->pkt_mtu;
      16         210 :   ulong            chunk  = sandbox->pkt_chunk;
      17         210 :   ulong            chunk0 = fd_dcache_compact_chunk0( sandbox, dcache );
      18         210 :   ulong            wmark  = fd_dcache_compact_wmark ( sandbox, dcache, mtu );
      19         210 :   ulong            depth  = fd_mcache_depth( mcache );
      20         210 :   ulong            sz     = pkt->buf_sz;
      21         210 :   uchar *          data   = fd_chunk_to_laddr( sandbox, chunk );
      22         210 :   ulong            ctl    = fd_frag_meta_ctl( /* orig */ 0, /* som */ 1, /* eom */ 1, /* err */ 0 );
      23         210 :   long             ts     = sandbox->wallclock;
      24             : 
      25         210 :   fd_memcpy( data, pkt->buf, sz );
      26         210 :   ulong tscomp = fd_frag_meta_ts_comp( ts );
      27         210 :   fd_mcache_publish( mcache, depth, seq, 0UL, chunk, sz, ctl, tscomp, tscomp );
      28             : 
      29         210 :   sandbox->pkt_seq_w = fd_seq_inc( seq, 1UL );
      30         210 :   sandbox->pkt_chunk = fd_dcache_compact_next( chunk, pkt->buf_sz, chunk0, wmark );
      31         210 : }
      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         210 :                           int                       flush ) {
      43             : 
      44         210 :   fd_quic_sandbox_t * sandbox = (fd_quic_sandbox_t *)ctx;
      45             : 
      46         420 :   for( ulong j=0UL; j<batch_cnt; j++ ) {
      47         210 :     fd_quic_sandbox_capture_pkt( sandbox, batch + j );
      48         210 :   }
      49             : 
      50         210 :   ulong _batch_idx[1];
      51         210 :   opt_batch_idx = opt_batch_idx ? opt_batch_idx : _batch_idx;
      52         210 :   *opt_batch_idx = batch_cnt;
      53             : 
      54         210 :   (void)flush;
      55         210 :   return FD_AIO_SUCCESS;
      56         210 : }
      57             : 
      58             : fd_frag_meta_t const *
      59         219 : fd_quic_sandbox_next_packet( fd_quic_sandbox_t * sandbox ) {
      60         219 :   fd_frag_meta_t * mcache = sandbox->pkt_mcache;
      61             : 
      62         219 :   ulong depth = fd_mcache_depth( mcache );
      63         219 :   ulong seq   = sandbox->pkt_seq_r;
      64         219 :   ulong mline = fd_mcache_line_idx( seq, depth );
      65             : 
      66         219 :   fd_frag_meta_t * frag = mcache + mline;
      67         219 :   if( FD_UNLIKELY( fd_seq_lt( frag->seq, seq ) ) ) return NULL;
      68         102 :   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         102 :   sandbox->pkt_seq_r = fd_seq_inc( seq, 1UL );
      76             : 
      77         102 :   return frag;
      78         219 : }
      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          45 : fd_quic_sandbox_align( void ) {
     115          45 :   return fd_ulong_max( fd_ulong_max( fd_ulong_max( fd_ulong_max(
     116          45 :       alignof(fd_quic_sandbox_t),
     117          45 :       fd_quic_align() ),
     118          45 :       fd_mcache_align() ),
     119          45 :       fd_dcache_align() ),
     120          45 :       FD_CHUNK_ALIGN );
     121          45 : }
     122             : 
     123             : ulong
     124             : fd_quic_sandbox_footprint( fd_quic_limits_t const * quic_limits,
     125             :                            ulong                    pkt_cnt,
     126          18 :                            ulong                    mtu ) {
     127             : 
     128          18 :   ulong root_align = fd_quic_sandbox_align();
     129          18 :   ulong quic_fp    = fd_quic_footprint( quic_limits );
     130          18 :   ulong mcache_fp  = fd_mcache_footprint( pkt_cnt, 0UL );
     131          18 :   ulong dcache_fp  = fd_dcache_footprint( fd_dcache_req_data_sz( mtu, pkt_cnt, 1UL, 1 ), 0UL );
     132             : 
     133          18 :   if( FD_UNLIKELY( !quic_fp   ) ) return 0UL;
     134          18 :   if( FD_UNLIKELY( !mcache_fp ) ) return 0UL;
     135          18 :   if( FD_UNLIKELY( !dcache_fp ) ) return 0UL;
     136             : 
     137          18 :   ulong l = FD_LAYOUT_INIT;
     138          18 :   l = FD_LAYOUT_APPEND( l, root_align,        sizeof(fd_quic_sandbox_t) );
     139          18 :   l = FD_LAYOUT_APPEND( l, fd_quic_align(),   quic_fp                   );
     140          18 :   l = FD_LAYOUT_APPEND( l, fd_mcache_align(), mcache_fp                 );
     141          18 :   l = FD_LAYOUT_APPEND( l, fd_dcache_align(), dcache_fp                 );
     142          18 :   return FD_LAYOUT_FINI( l, root_align );
     143          18 : }
     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           9 :                      ulong                    mtu ) {
     150             : 
     151           9 :   if( FD_UNLIKELY( !mem ) ) {
     152           0 :     FD_LOG_WARNING(( "NULL mem" ));
     153           0 :     return NULL;
     154           0 :   }
     155             : 
     156           9 :   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           9 :   ulong fp = fd_quic_sandbox_footprint( quic_limits, pkt_cnt, mtu );
     162           9 :   if( FD_UNLIKELY( !fp ) ) {
     163           0 :     FD_LOG_WARNING(( "invalid params" ));
     164           0 :     return NULL;
     165           0 :   }
     166             : 
     167           9 :   ulong root_align     = fd_quic_sandbox_align();
     168           9 :   ulong quic_fp        = fd_quic_footprint( quic_limits );
     169           9 :   ulong mcache_fp      = fd_mcache_footprint( pkt_cnt, 0UL );
     170           9 :   ulong dcache_data_sz = fd_dcache_req_data_sz( mtu, pkt_cnt, 1UL, 1 );
     171           9 :   ulong dcache_fp      = fd_dcache_footprint( dcache_data_sz, 0UL );
     172             : 
     173           9 :   FD_SCRATCH_ALLOC_INIT( l, mem );
     174           9 :   fd_quic_sandbox_t * sandbox    = FD_SCRATCH_ALLOC_APPEND( l, root_align,        sizeof(fd_quic_sandbox_t) );
     175           9 :   void *              quic_mem   = FD_SCRATCH_ALLOC_APPEND( l, fd_quic_align(),   quic_fp                   );
     176           9 :   void *              mcache_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_mcache_align(), mcache_fp                 );
     177           9 :   void *              dcache_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_dcache_align(), dcache_fp                 );
     178           9 :   FD_SCRATCH_ALLOC_FINI( l, root_align );
     179             : 
     180           9 :   ulong seq0 = 0UL;  /* the first packet in the capture always has sequence number 0 */
     181             : 
     182           9 :   *sandbox = (fd_quic_sandbox_t) {
     183           9 :     .quic       = fd_quic_join  ( fd_quic_new( quic_mem, quic_limits ) ),
     184           9 :     .pkt_mcache = fd_mcache_join( fd_mcache_new( mcache_mem, pkt_cnt, 0UL, seq0 ) ),
     185           9 :     .pkt_dcache = fd_dcache_join( fd_dcache_new( dcache_mem, dcache_data_sz, 0UL ) ),
     186           9 :     .pkt_seq_r  = seq0,
     187           9 :     .pkt_mtu    = mtu
     188           9 :   };
     189           9 :   void * shmlog = (void *)( (ulong)sandbox->quic + sandbox->quic->layout.log_off );
     190           9 :   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           9 :   FD_COMPILER_MFENCE();
     195           9 :   sandbox->magic = FD_QUIC_SANDBOX_MAGIC;
     196           9 :   FD_COMPILER_MFENCE();
     197             : 
     198           9 :   return sandbox;
     199           9 : }
     200             : 
     201             : fd_quic_sandbox_t *
     202             : fd_quic_sandbox_init( fd_quic_sandbox_t * sandbox,
     203         135 :                       int                 role ) {
     204             : 
     205         135 :   fd_quic_t *        quic     = sandbox->quic;
     206         135 :   fd_quic_config_t * quic_cfg = &quic->config;
     207             : 
     208         135 :   quic_cfg->role                  = role;
     209         135 :   quic_cfg->idle_timeout          = FD_QUIC_SANDBOX_IDLE_TIMEOUT;
     210         135 :   quic_cfg->initial_rx_max_stream_data = 512UL; /* arbitrary */
     211         135 :   memcpy( quic_cfg->identity_public_key, fd_quic_sandbox_self_ed25519_keypair + 32, 32 );
     212         135 :   memset( &quic->metrics, 0, sizeof(fd_quic_metrics_t) );
     213             : 
     214         135 :   fd_aio_t aio_tx = {
     215         135 :     .send_func = fd_quic_sandbox_aio_send,
     216         135 :     .ctx       = sandbox
     217         135 :   };
     218         135 :   fd_quic_set_aio_net_tx( quic, &aio_tx );
     219             : 
     220         135 :   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         135 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_INVALID ] == quic->limits.conn_cnt );
     227         135 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_HANDSHAKE ] == 0 );
     228         135 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_HANDSHAKE_COMPLETE ] == 0 );
     229         135 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_ACTIVE ] == 0 );
     230         135 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_PEER_CLOSE ] == 0 );
     231         135 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_ABORT ] == 0 );
     232         135 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_CLOSE_PENDING ] == 0 );
     233         135 :   FD_TEST( quic->metrics.conn_state_cnt[ FD_QUIC_CONN_STATE_DEAD ] == 0 );
     234             : 
     235         135 :   fd_quic_state_t * state = fd_quic_get_state( quic );
     236         135 :   state->now = 1L;
     237         135 :   sandbox->wallclock = 1L;
     238         135 :   sandbox->pkt_seq_r = 0UL;
     239         135 :   sandbox->pkt_seq_w = 0UL;
     240         135 :   ulong pkt_depth = fd_mcache_depth( sandbox->pkt_mcache );
     241       20103 :   for( ulong seq=0UL; seq<pkt_depth; seq++ ) {
     242       19968 :     ulong line = fd_mcache_line_idx( seq, pkt_depth );
     243       19968 :     sandbox->pkt_mcache[ line ].seq = fd_seq_dec( seq, 1UL );
     244       19968 :   }
     245         135 :   sandbox->pkt_chunk = fd_dcache_compact_chunk0( sandbox, sandbox->pkt_dcache );
     246             : 
     247             :   /* skip ahead the log seq no */
     248         135 :   fd_quic_log_tx_t * log_tx = state->log_tx;
     249         135 :   log_tx->seq += 4093; /* prime */
     250             : 
     251         135 :   return sandbox;
     252         135 : }
     253             : 
     254             : void *
     255           9 : fd_quic_sandbox_delete( fd_quic_sandbox_t * mem ) {
     256             : 
     257           9 :   if( FD_UNLIKELY( !mem ) ) {
     258           0 :     FD_LOG_WARNING(( "NULL mem" ));
     259           0 :     return NULL;
     260           0 :   }
     261             : 
     262           9 :   fd_quic_sandbox_t * sandbox = (fd_quic_sandbox_t *)mem;
     263           9 :   if( FD_UNLIKELY( sandbox->magic != FD_QUIC_SANDBOX_MAGIC ) ) {
     264           0 :     FD_LOG_WARNING(( "invalid magic" ));
     265           0 :     return NULL;
     266           0 :   }
     267             : 
     268           9 :   FD_COMPILER_MFENCE();
     269           9 :   sandbox->magic = 0UL;
     270           9 :   FD_COMPILER_MFENCE();
     271             : 
     272           9 :   fd_quic_delete  ( fd_quic_leave  ( sandbox->quic       ) );
     273           9 :   fd_mcache_delete( fd_mcache_leave( sandbox->pkt_mcache ) );
     274           9 :   fd_dcache_delete( fd_dcache_leave( sandbox->pkt_dcache ) );
     275             : 
     276           9 :   return mem;
     277           9 : }
     278             : 
     279             : fd_quic_conn_t *
     280             : fd_quic_sandbox_new_conn_established( fd_quic_sandbox_t * sandbox,
     281      300120 :                                       fd_rng_t *          rng ) {
     282             : 
     283      300120 :   fd_quic_t * quic = sandbox->quic;
     284             : 
     285             :   /* fd_quic_t conn IDs are always 8 bytes */
     286      300120 :   ulong             our_conn_id_u64 = fd_rng_ulong( rng );
     287             : 
     288             :   /* the peer may choose a conn ID size 1 to 16 bytes
     289             :      For now, pick 8 bytes too */
     290      300120 :   ulong             peer_conn_id_u64 = fd_rng_ulong( rng );
     291      300120 :   fd_quic_conn_id_t peer_conn_id     = fd_quic_conn_id_new( &peer_conn_id_u64, 8UL );
     292             : 
     293      300120 :   fd_quic_conn_t * conn = fd_quic_conn_create(
     294      300120 :       /* quic         */ quic,
     295      300120 :       /* our_conn_id  */ our_conn_id_u64,
     296      300120 :       /* peer_conn_id */ &peer_conn_id,
     297      300120 :       /* dst_ip_addr  */ FD_QUIC_SANDBOX_PEER_IP4,
     298      300120 :       /* dst_udp_addr */ FD_QUIC_SANDBOX_PEER_PORT,
     299      300120 :       /* src_ip_addr  */ FD_QUIC_SANDBOX_SELF_IP4,
     300      300120 :       /* src_udp_addr */ FD_QUIC_SANDBOX_SELF_PORT,
     301      300120 :       /* server       */ quic->config.role == FD_QUIC_ROLE_SERVER );
     302      300120 :   if( FD_UNLIKELY( !conn ) ) {
     303           0 :     FD_LOG_WARNING(( "fd_quic_conn_create failed" ));
     304           0 :     return NULL;
     305           0 :   }
     306             : 
     307      300120 :   conn->state       = FD_QUIC_CONN_STATE_ACTIVE;
     308      300120 :   conn->established = 1;
     309             : 
     310             :   /* Mock a completed handshake */
     311      300120 :   conn->handshake_complete = 1;
     312      300120 :   conn->keys_avail         = 1U<<fd_quic_enc_level_appdata_id;
     313             : 
     314      300120 :   conn->idle_timeout_ns    = FD_QUIC_SANDBOX_IDLE_TIMEOUT;
     315      300120 :   conn->last_activity      = sandbox->wallclock;
     316             : 
     317             :   /* Reset flow control limits */
     318      300120 :   conn->tx_max_data           = 0UL;
     319      300120 :   conn->tx_tot_data           = 0UL;
     320      300120 :   conn->srx->rx_max_data      = 0UL;
     321      300120 :   conn->srx->rx_tot_data      = 0UL;
     322      300120 :   conn->srx->rx_max_data_ackd = 0UL;
     323      300120 :   conn->tx_initial_max_stream_data_uni = 0UL;
     324             : 
     325      300120 :   fd_quic_state_t * state = fd_quic_get_state( quic );
     326      300120 :   fd_quic_svc_timers_schedule( state->svc_timers, conn, sandbox->wallclock );
     327             : 
     328             :   /* TODO set a realistic packet number */
     329             : 
     330      300120 :   return conn;
     331      300120 : }
     332             : 
     333             : void
     334             : fd_quic_sandbox_send_frame( fd_quic_sandbox_t * sandbox,
     335             :                             fd_quic_conn_t *    conn,
     336             :                             fd_quic_pkt_t *     pkt_meta,
     337             :                             uchar const *       frame_ptr,
     338   120092950 :                             ulong               frame_sz ) {
     339             : 
     340             :   /* TODO consider crafting a real app packet instead of bypassing
     341             :           packet processing checks */
     342             : 
     343   120092950 :   fd_quic_t * quic = sandbox->quic;
     344             : 
     345             :   /* set pkt_type to FD_QUIC_PKT_TYPE_ONE_RTT as it allows all
     346             :    * frame types */
     347   120092950 :   uint pkt_type = FD_QUIC_PKT_TYPE_ONE_RTT;
     348             : 
     349   120092950 :   ulong rc = fd_quic_handle_v1_frame( quic, conn, pkt_meta, pkt_type, frame_ptr, frame_sz );
     350   120092950 :   if( FD_UNLIKELY( rc==FD_QUIC_PARSE_FAIL ) ) return;
     351   120092935 :   if( FD_UNLIKELY( rc==0UL || rc>frame_sz ) ) {
     352           0 :     FD_LOG_CRIT(( "Invalid fd_quic_handle_v1_frame return value (rc=%#lx frame_sz=%#lx)", rc, frame_sz ));
     353           0 :   }
     354             : 
     355   120092935 : }
     356             : 
     357             : void
     358             : fd_quic_sandbox_send_lone_frame( fd_quic_sandbox_t * sandbox,
     359             :                                  fd_quic_conn_t *    conn,
     360             :                                  uchar const *       frame,
     361   120092944 :                                  ulong               frame_sz ) {
     362             : 
     363   120092944 :   FD_TEST( frame_sz <= sandbox->pkt_mtu );
     364             : 
     365   120092944 :   ulong pkt_num = conn->exp_pkt_number[2]++;
     366             : 
     367   120092944 :   ulong quic_pkt_sz = frame_sz;  /* TODO mock some QUIC packetization overhead */
     368             : 
     369   120092944 :   fd_quic_pkt_t pkt_meta = {
     370   120092944 :     .ip4 = {{
     371   120092944 :       .verihl       = FD_IP4_VERIHL(4,5),
     372   120092944 :       .net_tot_len  = (ushort)( 20 + 8 + quic_pkt_sz ),
     373   120092944 :       .net_frag_off = 0x4000u, /* don't fragment */
     374   120092944 :       .ttl          = 64,
     375   120092944 :       .protocol     = FD_IP4_HDR_PROTOCOL_UDP,
     376   120092944 :       .saddr        = FD_QUIC_SANDBOX_PEER_IP4,
     377   120092944 :       .daddr        = FD_QUIC_SANDBOX_SELF_IP4,
     378   120092944 :     }},
     379   120092944 :     .udp = {{
     380   120092944 :       .net_sport = FD_QUIC_SANDBOX_PEER_PORT,
     381   120092944 :       .net_dport = FD_QUIC_SANDBOX_SELF_PORT,
     382   120092944 :       .net_len   = (ushort)( 8 + quic_pkt_sz ),
     383   120092944 :     }},
     384   120092944 :     .pkt_number = pkt_num,
     385   120092944 :     .rcv_time   = sandbox->wallclock,
     386   120092944 :     .enc_level  = fd_quic_enc_level_appdata_id,
     387   120092944 :   };
     388             : 
     389   120092944 :   fd_quic_sandbox_send_frame( sandbox, conn, &pkt_meta, frame, frame_sz );
     390             : 
     391   120092944 :   fd_quic_lazy_ack_pkt( sandbox->quic, conn, &pkt_meta );
     392             : 
     393             :   /* Synchronize log seq[0] from tx to rx */
     394   120092944 :   fd_quic_log_tx_seq_update( fd_quic_get_state( sandbox->quic )->log_tx );
     395   120092944 : }
     396             : 
     397             : void
     398             : fd_quic_sandbox_send_ping_pkt( fd_quic_sandbox_t * sandbox,
     399             :                                fd_quic_conn_t *    conn,
     400         210 :                                ulong               pktnum ) {
     401             : 
     402         210 :   uchar pkt_buf[ 256 ];
     403         210 :   pkt_buf[0] = fd_quic_one_rtt_h0( /* spin */         0,
     404         210 :                                    /* key_phase */    !!conn->key_phase,
     405         210 :                                    /* pktnum_len-1 */ 3 );
     406         210 :   memcpy( pkt_buf+1, &conn->our_conn_id, FD_QUIC_CONN_ID_SZ );
     407         210 :   uint pktnum_comp = fd_uint_bswap( (uint)( pktnum & UINT_MAX ) );
     408         210 :   memcpy( pkt_buf+9, &pktnum_comp, 4 );
     409         210 :   pkt_buf[13] = 0x01;  /* PING frame */
     410         210 :   memset( pkt_buf+14, 0, 18UL );
     411             : 
     412         210 :   fd_quic_crypto_keys_t * keys = &conn->keys[fd_quic_enc_level_appdata_id][0];
     413         210 :   ulong out_sz = 48UL;
     414         210 :   int crypt_res = fd_quic_crypto_encrypt( pkt_buf, &out_sz, pkt_buf, 13UL, pkt_buf+13, 19UL, keys, keys, pktnum );
     415         210 :   FD_TEST( crypt_res==FD_QUIC_SUCCESS );
     416             : 
     417         210 :   fd_quic_pkt_t pkt = {
     418         210 :     .ip4 = {{
     419         210 :       .verihl       = FD_IP4_VERIHL(4,5),
     420         210 :       .net_tot_len  = 28,
     421         210 :       .net_frag_off = 0x4000u, /* don't fragment */
     422         210 :       .ttl          = 64,
     423         210 :       .protocol     = FD_IP4_HDR_PROTOCOL_UDP,
     424         210 :       .saddr        = FD_QUIC_SANDBOX_PEER_IP4,
     425         210 :       .daddr        = FD_QUIC_SANDBOX_SELF_IP4,
     426         210 :     }},
     427         210 :     .udp = {{
     428         210 :       .net_sport = FD_QUIC_SANDBOX_PEER_PORT,
     429         210 :       .net_dport = FD_QUIC_SANDBOX_SELF_PORT,
     430         210 :       .net_len   = 8,
     431         210 :     }},
     432         210 :     .pkt_number = pktnum,
     433         210 :     .rcv_time   = sandbox->wallclock,
     434         210 :     .enc_level  = fd_quic_enc_level_appdata_id,
     435         210 :   };
     436             : 
     437         210 :   fd_quic_process_quic_packet_v1( sandbox->quic, &pkt, pkt_buf, out_sz );
     438         210 : }

Generated by: LCOV version 1.14