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 : }
|