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

Generated by: LCOV version 1.14