LCOV - code coverage report
Current view: top level - waltz/quic/tests - fd_quic_sandbox.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 6 10 60.0 %
Date: 2025-01-08 12:08:44 Functions: 0 3 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_quic_tests_fd_quic_sandbox_h
       2             : #define HEADER_fd_src_waltz_quic_tests_fd_quic_sandbox_h
       3             : 
       4             : #include "../fd_quic.h"
       5             : #include "../log/fd_quic_log_user.h"
       6             : #include "../../../tango/mcache/fd_mcache.h"
       7             : #include "../../../tango/dcache/fd_dcache.h"
       8             : #include "../../../util/net/fd_ip4.h"
       9             : 
      10             : /* fd_quic_sandbox_t is used to setup and analyze a conversation with
      11             :    fd_quic.  It manages an instrumented fd_quic_t instance and records
      12             :    its outgoing packets.   The packet capture is a ring buffer
      13             :    (mcache/dcache pair) that captures the last N packets.
      14             : 
      15             :    fd_quic_sandbox_t is single-threaded only.  fd_quic_sandbox_t cannot
      16             :    be shared across different address spaces. The usual mcache lockless
      17             :    concurrency patterns for accessing the captured packet ring are thus
      18             :    unnecessary.  It is not safe to declare a fd_quic_sandbox_t variable,
      19             :    use the object lifecycle API instead. */
      20             : 
      21             : struct fd_quic_sandbox {
      22             :   /* Static members (values only changed by new/delete) */
      23             : 
      24             :   ulong            magic;       /* ==FD_QUIC_SANDBOX_MAGIC */
      25             :   fd_quic_t *      quic;        /* the QUIC instance to be tested */
      26             :   fd_frag_meta_t * pkt_mcache;  /* captured packet descriptor */
      27             :   void *           pkt_dcache;  /* captured packet data */
      28             :   ulong            pkt_mtu;     /* captured packet max payload sz */
      29             :   fd_quic_log_rx_t log_rx[1];
      30             : 
      31             :   /* State */
      32             : 
      33             :   ulong  pkt_seq_r;   /* seq no of next packet not yet read */
      34             :   ulong  pkt_seq_w;   /* seq no of next packet to publish */
      35             :   ulong  pkt_chunk;   /* publisher chunk index */
      36             :   ulong  wallclock;   /* time as seen by fd_quic (ns) */
      37             : };
      38             : 
      39             : typedef struct fd_quic_sandbox fd_quic_sandbox_t;
      40             : 
      41             : /* FD_QUIC_SANDBOX_MAGIC is a unique random number identifying an
      42             :    fd_quic_sandbox_t object. */
      43             : 
      44           3 : #define FD_QUIC_SANDBOX_MAGIC (0xf072dd5e98bb6e91UL)  /* random */
      45             : 
      46             : /* FD_QUIC_SANDBOX_SELF_IP4 is the default IP address of the sandbox
      47             :    fd_quic_t. */
      48             : 
      49           3 : #define FD_QUIC_SANDBOX_SELF_IP4  FD_IP4_ADDR( 30, 0, 0, 1 )
      50             : 
      51             : /* FD_QUIC_SANDBOX_PEER_IP4 is the default IP address of the mock peer
      52             :    that the sandbox fd_quic_t is talking with. */
      53             : 
      54      300000 : #define FD_QUIC_SANDBOX_PEER_IP4  FD_IP4_ADDR( 30, 0, 0, 2 )
      55             : 
      56             : /* FD_QUIC_SANDBOX_SELF_PORT is the default UDP port of the sandbox
      57             :    fd_quic_t. */
      58             : 
      59    79319457 : #define FD_QUIC_SANDBOX_SELF_PORT ((ushort)9000)
      60             : 
      61             : /* FD_QUIC_SANDBOX_PEER_PORT is the default UDP port of the mock peer
      62             :    that the sandbox fd_quic_t is talking with. */
      63             : 
      64   158938896 : #define FD_QUIC_SANDBOX_PEER_PORT ((ushort)9001)
      65             : 
      66             : /* FD_QUIC_SANDBOX_IDLE_TIMEOUT is the default fd_quic idle timeout. */
      67             : 
      68      300003 : #define FD_QUIC_SANDBOX_IDLE_TIMEOUT (1000000000UL)  /* 1s */
      69             : 
      70             : /* Object lifecycle ***************************************************/
      71             : 
      72             : FD_PROTOTYPES_BEGIN
      73             : 
      74             : /* fd_quic_sandbox_{align,footprint} describe requirements for the
      75             :    memory region backing an fd_quic_sandbox_t.
      76             : 
      77             :    quic_limits are the parameters for the fd_quic_t owned by
      78             :    fd_quic_sandbox_t.  pkt_cnt are the number of packets that are
      79             :    buffered (must be a power of 2).  mtu is the max size of each packet
      80             :    (only the UDP datagram, not including Ethernet or IPv4 headers).
      81             : 
      82             :    fd_quic_footprint returns 0UL if any of the parameters are invalid
      83             :    and can thus be used for fast validation. */
      84             : 
      85             : ulong
      86             : fd_quic_sandbox_align( void );
      87             : 
      88             : ulong
      89             : fd_quic_sandbox_footprint( fd_quic_limits_t const * quic_limits,
      90             :                            ulong                    pkt_cnt,
      91             :                            ulong                    mtu );
      92             : 
      93             : /* fd_quic_sandbox_new formats the memory region 'mem' for use as an
      94             :    fd_quic_sandbox_t.  The arguments must match those given to
      95             :    fd_quic_sandbox_footprint when creating the memory region (assumes
      96             :    that parameters are valid, i.e. footprint returned non-zero).
      97             :    Returns mem on success.  On failure, returns NULL and logs reason for
      98             :    failure. */
      99             : 
     100             : fd_quic_sandbox_t *
     101             : fd_quic_sandbox_new( void *                   mem,
     102             :                      fd_quic_limits_t const * quic_limits,
     103             :                      ulong                    pkt_cnt,
     104             :                      ulong                    mtu );
     105             : 
     106             : /* fd_quic_sandbox_init resets the fd_quic_sandbox_t to a common state.
     107             : 
     108             :    sandbox points to a local join to the fd_quic_sandbox_t.
     109             :    role is one of FD_QUIC_ROLE_{CLIENT,SERVER}.
     110             : 
     111             :    On return,
     112             :    - the fake wallclock is 0UL
     113             :    - the embedded fd_quic_t instance is in 'initialized state' (via
     114             :      fd_quic_init), having no connections and empty object pools
     115             :    - the packet capture ring is empty
     116             :    - the idle_timeout is 1s
     117             :    - the local identity key is Ed25519 secret of b'\x41' * 32 */
     118             : 
     119             : fd_quic_sandbox_t *
     120             : fd_quic_sandbox_init( fd_quic_sandbox_t * sandbox,
     121             :                       int                 role );
     122             : 
     123             : /* fd_quic_sandbox_delete destroys an fd_quic_sandbox_t object and
     124             :    releases the memory region back to the caller. */
     125             : 
     126             : void *
     127             : fd_quic_sandbox_delete( fd_quic_sandbox_t * mem );
     128             : 
     129             : FD_PROTOTYPES_END
     130             : 
     131             : /* Encryption *********************************************************/
     132             : 
     133             : FD_PROTOTYPES_BEGIN
     134             : 
     135             : /* fd_quic_sandbox_{self,peer}_ed25519_keypair is the default Ed25519
     136             :    key pair of the sandbox fd_quic_t and the mock peer respectively.
     137             : 
     138             :    The first 32 bytes is the scalar/private key, the last 32 bytes is
     139             :    the encoded public key. */
     140             : 
     141             : extern uchar const fd_quic_sandbox_self_ed25519_keypair[64];
     142             : extern uchar const fd_quic_sandbox_peer_ed25519_keypair[64];
     143             : 
     144             : /* fd_quic_sandbox_aes128_{key,iv} are the default AES-128-GCM secret
     145             :    key and IV of the sandbox fd_quic_t and mock peer.  They are the
     146             :    same for anywhere symmetric crypto is used, except for the QUIC
     147             :    initial layer where the protocol hardcoded keys are useds. */
     148             : 
     149             : extern uchar const fd_quic_sandbox_aes128_key[16];
     150             : extern uchar const fd_quic_sandbox_aes128_iv [12];
     151             : 
     152             : FD_PROTOTYPES_END
     153             : 
     154             : /* Packet Capture *****************************************************/
     155             : 
     156             : FD_PROTOTYPES_BEGIN
     157             : 
     158             : /* fd_quic_sandbox_next_packet reads the next buffered packet that
     159             :    fd_quic_t might have sent earlier.  Returns a pointer to the frag
     160             :    descriptor and advances the read index if a packet was available.
     161             :    Returns NULL if there is no new packet.  If packet loss occurs due
     162             :    to fd_quic having overrun the reader, logs a warning. Use
     163             :    fd_quic_sandbox_packet_data to get a pointer to the data. */
     164             : 
     165             : fd_frag_meta_t const *
     166             : fd_quic_sandbox_next_packet( fd_quic_sandbox_t * sandbox );
     167             : 
     168             : /* fd_quic_sandbox_packet_data returns a pointer to the first byte of
     169             :    packet data, given a fd_frag_meta_t in the sandbox pkt cap mcache. */
     170             : 
     171             : FD_FN_CONST static inline uchar *
     172             : fd_quic_sandbox_packet_data( fd_quic_sandbox_t *    sandbox,
     173           0 :                              fd_frag_meta_t const * frag ) {
     174           0 :   void * base = (void *)sandbox;  /* aligned by FD_CHUNK_ALIGN */
     175           0 :   return fd_chunk_to_laddr( base, frag->chunk );
     176           0 : }
     177             : 
     178             : FD_PROTOTYPES_END
     179             : 
     180             : /* Mock API ***********************************************************/
     181             : 
     182             : /* fd_quic_sandbox_new_conn_established injects a new established
     183             :    connection into the fd_quic_t state.  Uses the fd_rng_t to randomly
     184             :    populate identifiers such as the conn ID.  Returns the newly created
     185             :    fd_quic_conn_t on success (owned by fd_quic_t).  Returns NULL if no
     186             :    free conn slots are available or the conn ID map is full.
     187             : 
     188             :    Note that the returned pointer may become invalid at some point
     189             :    because the fd_quic_t might free it (e.g. connection failed due to
     190             :    protocol error).
     191             : 
     192             :    The new connection is configured as such:
     193             :    - The QUIC version is v1
     194             :    - Zero quota for streams
     195             :    - Zero quota for stream data
     196             :    - Zero quota for data
     197             :    - The self endpoint is FD_QUIC_SANDBOX_SELF_IP4:FD_QUIC_SANDBOX_SELF_PORT
     198             :    - The peer endpoint is FD_QUIC_SANDBOX_PEER_IP4:FD_QUIC_SANDBOX_PEER_PORT */
     199             : 
     200             : fd_quic_conn_t *
     201             : fd_quic_sandbox_new_conn_established( fd_quic_sandbox_t * sandbox,
     202             :                                       fd_rng_t *          rng );
     203             : 
     204             : /* fd_quic_sandbox_send_frame sends the given QUIC frame to the sandbox
     205             :    fd_quic instance via the given connection.  This entrypoint side
     206             :    steps decryption and jumps directly to frame handling.  Some frame
     207             :    handlers require packet metadata.
     208             :    The memory region at [frame,frame+frame_sz) contains the wire
     209             :    encoding of the frame. */
     210             : 
     211             : void
     212             : fd_quic_sandbox_send_frame( fd_quic_sandbox_t * sandbox,
     213             :                             fd_quic_conn_t *    conn,
     214             :                             fd_quic_pkt_t *     pkt_meta,
     215             :                             uchar const *       frame,
     216             :                             ulong               frame_sz );
     217             : 
     218             : /* fd_quic_sandbox_send_lone_frame wraps fd_quic_sandbox_send_frame but
     219             :    with realistic packet meta.  It simulates a frame sent in a single
     220             :    QUIC packet and advances the packet number accordingly. */
     221             : 
     222             : void
     223             : fd_quic_sandbox_send_lone_frame( fd_quic_sandbox_t * sandbox,
     224             :                                  fd_quic_conn_t *    conn,
     225             :                                  uchar const *       frame,
     226             :                                  ulong               frame_sz );
     227             : 
     228             : /* fd_quic_sandbox_send_ping_pkt sends a 1-RTT packet containing only a
     229             :    PING frame. */
     230             : 
     231             : void
     232             : fd_quic_sandbox_send_ping_pkt( fd_quic_sandbox_t * sandbox,
     233             :                                fd_quic_conn_t *    conn,
     234             :                                ulong               pktnum );
     235             : 
     236             : FD_PROTOTYPES_END
     237             : 
     238             : #endif /* HEADER_fd_src_waltz_quic_tests_fd_quic_sandbox_h */

Generated by: LCOV version 1.14