Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_tests_fd_quic_test_helpers_h 2 : #define HEADER_fd_src_waltz_quic_tests_fd_quic_test_helpers_h 3 : 4 : #include "../fd_quic.h" 5 : #include "../fd_quic_private.h" 6 : #include "../../aio/fd_aio_pcapng.h" 7 : #include "../../udpsock/fd_udpsock.h" 8 : #include "../../tls/test_tls_helper.h" 9 : #include "../../../ballet/txn/fd_txn.h" /* FD_TXN_MTU */ 10 : 11 : #include <stdio.h> 12 : 13 : /* Common helpers for QUIC tests. The tests using these gain the 14 : following command-line options: 15 : 16 : --pcap <path> Append test traffic to pcapng 1.0 at given file 17 : path (encryption secrets included) */ 18 : 19 : /* fd_quic_virtual_pair_t is used to connect two local QUICs via 20 : direct fd_aio. Optionally supports packet capture. */ 21 : 22 : struct fd_quic_virtual_pair { 23 : fd_quic_t * quic_a; 24 : fd_quic_t * quic_b; 25 : 26 : /* aio_{a2b,b2a} point to the first hop of each aio chain */ 27 : fd_aio_t const * aio_a2b; 28 : fd_aio_t const * aio_b2a; 29 : 30 : fd_aio_pcapng_t pcapng_a2b; 31 : fd_aio_pcapng_t pcapng_b2a; 32 : }; 33 : typedef struct fd_quic_virtual_pair fd_quic_virtual_pair_t; 34 : 35 : FD_PROTOTYPES_BEGIN 36 : 37 : extern FILE * fd_quic_test_pcap; 38 : 39 : /* fd_quic_test_boot boots the QUIC test environment. 40 : Should be called after fd_boot(). 41 : 42 : fd_quic_test_halt halts the QUIC test environment. 43 : Should be called before fd_halt(). */ 44 : 45 : void 46 : fd_quic_test_boot( int * pargc, 47 : char *** pargv ); 48 : void 49 : fd_quic_test_halt( void ); 50 : 51 : void 52 : fd_quic_config_anonymous( fd_quic_t * quic, 53 : int role ); 54 : 55 : void 56 : fd_quic_config_test_signer( fd_quic_t * quic, 57 : fd_tls_test_sign_ctx_t * sign_ctx ); 58 : 59 : /* fd_quic_new_anonymous creates an anonymous QUIC instance with the 60 : given limits. Vacant config fields are auto-generated, except for 61 : role (server or client). Returns QUIC instance without local join on 62 : success. Halts program on error. Caller is responsible for cleaning 63 : up QUIC. */ 64 : 65 : fd_quic_t * 66 : fd_quic_new_anonymous( fd_wksp_t * wksp, 67 : fd_quic_limits_t const * limits, 68 : int role, 69 : fd_rng_t * rng ); 70 : 71 : /* fd_quic_new_anonymous_small is like fd_quic_new_anonymous but with 72 : arbitrary small limits for convenience. */ 73 : 74 : fd_quic_t * 75 : fd_quic_new_anonymous_small( fd_wksp_t * wksp, 76 : int role, 77 : fd_rng_t * rng ); 78 : 79 : /* fd_quic_sync_clocks sets the clock of two QUICs to 'now'. */ 80 : static inline void 81 : fd_quic_sync_clocks( fd_quic_t * quicA, 82 : fd_quic_t * quicB, 83 146970 : long now ) { 84 146970 : fd_quic_get_state( quicA )->now = fd_quic_get_state( quicB )->now = now; 85 146970 : } 86 : 87 : /* fd_quic_virtual_pair_init sets up an aio loop between the two given QUIC 88 : objects. That is, an fd_aio_send() call by quicA will trigger 89 : a synchronous callback to the aio receive to the quicB. (FIXME This 90 : assumes no reentrancy in QUIC) If user requested pcap, causes 91 : packets to get logged. May only be called once per thread. Any 92 : allocated resources get released at halt. */ 93 : 94 : void 95 : fd_quic_virtual_pair_init( fd_quic_virtual_pair_t * pair, 96 : fd_quic_t * quicA, 97 : fd_quic_t * quicB ); 98 : 99 : /* fd_quic_virtual_pair_fini destroys an aio loop between the two given 100 : QUIC objects. */ 101 : 102 : void 103 : fd_quic_virtual_pair_fini( fd_quic_virtual_pair_t * pair ); 104 : 105 : void 106 : fd_quic_test_cb_tls_keylog( void * quic_ctx, 107 : char const * line ); 108 : 109 : FD_PROTOTYPES_END 110 : 111 : /* fd_quic_udpsock is a command-line helper for creating an UDP channel 112 : over AF_XDP or UDP sockets. */ 113 : 114 : struct fd_quic_udpsock { 115 : int type; 116 0 : # define FD_QUIC_UDPSOCK_TYPE_UDPSOCK 2 117 : 118 : uint listen_ip; 119 : ushort listen_port; 120 : 121 : fd_wksp_t * wksp; /* Handle to the workspace owning the objects */ 122 : union { 123 : struct { 124 : fd_udpsock_t * sock; 125 : int sock_fd; 126 : } udpsock; 127 : }; 128 : 129 : fd_aio_t const * aio; 130 : }; 131 : typedef struct fd_quic_udpsock fd_quic_udpsock_t; 132 : 133 : FD_PROTOTYPES_BEGIN 134 : 135 : fd_quic_udpsock_t * 136 : fd_quic_client_create_udpsock(fd_quic_udpsock_t * udpsock, 137 : fd_wksp_t * wksp, 138 : fd_aio_t const * rx_aio, 139 : uint listen_ip); 140 : 141 : fd_quic_udpsock_t * 142 : fd_quic_udpsock_create( void * _sock, 143 : int * argc, 144 : char *** argv, 145 : fd_wksp_t * wksp, 146 : fd_aio_t const * rx_aio ); 147 : 148 : void * 149 : fd_quic_udpsock_destroy( fd_quic_udpsock_t * udpsock ); 150 : 151 : void 152 : fd_quic_udpsock_service( fd_quic_udpsock_t const * udpsock ); 153 : 154 : 155 : /* fd_quic_netem injects packet loss and reordering into an aio link. */ 156 : 157 : struct fd_quic_netem_reorder_buf { 158 : ulong sz; 159 : uchar buf[2048]; 160 : }; 161 : 162 : struct fd_quic_netem { 163 : fd_aio_t local; 164 : fd_aio_t const * dst; 165 : float thresh_drop; 166 : float thresh_reorder; 167 : 168 : struct fd_quic_netem_reorder_buf reorder_buf[2]; 169 : int reorder_mru; /* most recently written reorder buf */ 170 : 171 : ulong drop_sequence; /* defines a drop-sequence for next 64 outgoing packets */ 172 : 173 : long * now_ptr; /* points to test 'now' */ 174 : long one_way_latency; 175 : }; 176 : 177 : typedef struct fd_quic_netem fd_quic_netem_t; 178 : 179 : fd_quic_netem_t * 180 : fd_quic_netem_init( fd_quic_netem_t * netem, 181 : float thres_drop, 182 : float thres_reorder, 183 : long * now_ptr ); 184 : 185 : /* fd_quic_netem_set_drop sets a drop sequence for outgoing packets. 186 : 'drop_sequence' is an ordered bitset interpreted from right to left, 187 : where 1 signals a drop. This function can specify behavior for at most 188 : the next 64 packets. Subsequent calls to this function overwrite the 189 : previous call. Non-zero thres_drop and/or thres_reorder only apply if 190 : packet is not dropped by the deterministic drop_sequence. 191 : To get only deterministic drops, set thres_drop and thres_reorder to 0. */ 192 : 193 : void 194 : fd_quic_netem_set_drop( fd_quic_netem_t * netem, 195 : ulong drop_sequence ); 196 : 197 : /* fd_quic_netem_set_one_way_latency sets the one_way_latency 198 : for the network emulation. Each outgoing packet will increment 199 : *now_ptr by one_way_latency. */ 200 : 201 : void 202 : fd_quic_netem_set_one_way_latency( fd_quic_netem_t * netem, 203 : long one_way_latency ); 204 : 205 : /* fd_quic_netem_send implements fd_aio_send for fd_quic_netem_t. */ 206 : 207 : int 208 : fd_quic_netem_send( void * ctx, /* fd_quic_net_em_t */ 209 : fd_aio_pkt_info_t const * batch, 210 : ulong batch_cnt, 211 : ulong * opt_batch_idx, 212 : int flush ); 213 : 214 : FD_PROTOTYPES_END 215 : 216 : #endif /* HEADER_fd_src_waltz_quic_tests_fd_quic_test_helpers_h */