xref: /freebsd/crypto/openssl/test/radix/quic_tests.c (revision 78e936b2d0b5e6554425009199be31e76bc67c10)
1 /*
2  * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include "internal/quic_reactor.h"
11 #include "../../ssl/rio/poll_builder.h"
12 
13 #if defined(_AIX)
14 /*
15  * Some versions of AIX define macros for events and revents for use when
16  * accessing pollfd structures (see Github issue #24236). That interferes
17  * with our use of these names here. We simply undef them.
18  */
19 #undef revents
20 #undef events
21 #endif
22 
23 /*
24  * Test Scripts
25  * ============================================================================
26  */
27 
28 /*
29  * Test: simple_conn
30  * -----------------
31  */
32 DEF_SCRIPT(simple_conn, "simple connection to server")
33 {
34     size_t i;
35 
36     for (i = 0; i < 2; ++i) {
37         if (i == 0) {
38             OP_SIMPLE_PAIR_CONN_D();
39         } else {
40             OP_CLEAR();
41             OP_SIMPLE_PAIR_CONN();
42         }
43 
44         OP_WRITE_B(C, "apple");
45 
46         OP_ACCEPT_CONN_WAIT(L, La, 0);
47         OP_ACCEPT_CONN_NONE(L);
48 
49         OP_READ_EXPECT_B(La, "apple");
50         OP_WRITE_B(La, "orange");
51         OP_READ_EXPECT_B(C, "orange");
52     }
53 }
54 
55 DEF_SCRIPT(simple_thread_child,
56     "test that RADIX multithreading is working (child)")
57 {
58 }
59 
60 /*
61  * Test: simple_thread
62  * -------------------
63  */
64 DEF_SCRIPT(simple_thread,
65     "test that RADIX multithreading is working")
66 {
67     size_t i;
68 
69     for (i = 0; i < 2; ++i)
70         OP_SPAWN_THREAD(simple_thread_child);
71 }
72 
73 /*
74  * Test: ssl_poll
75  * --------------
76  */
77 DEF_SCRIPT(ssl_poll_child,
78     "test that SSL_poll is working (child)")
79 {
80     OP_SLEEP(100);
81     OP_WRITE_B(C0, "extra");
82 }
83 
DEF_FUNC(ssl_poll_check)84 DEF_FUNC(ssl_poll_check)
85 {
86     int ok = 0;
87     SSL *La, *Lax[4];
88     SSL_POLL_ITEM items[6] = { 0 }, expected_items[6] = { 0 };
89     size_t result_count = 0, i;
90     const struct timeval z_timeout = { 0 }, *p_timeout = &z_timeout;
91     struct timeval timeout = { 0 };
92     uint64_t mode;
93     size_t expected_result_count;
94     OSSL_TIME time_before, time_after;
95 
96     F_POP(mode);
97     REQUIRE_SSL_5(La, Lax[0], Lax[1], Lax[2], Lax[3]);
98 
99     items[0].desc = SSL_as_poll_descriptor(La);
100     items[0].events = 0;
101     items[0].revents = 0;
102 
103     for (i = 0; i < 4; ++i) {
104         items[i + 1].desc = SSL_as_poll_descriptor(Lax[i]);
105         items[i + 1].events = SSL_POLL_EVENT_R | SSL_POLL_EVENT_I;
106         items[i + 1].revents = 0;
107     }
108 
109     items[5].desc = SSL_as_poll_descriptor(SSL_get0_listener(La));
110 
111     switch (mode) {
112     case 0: /* Nothing ready */
113     case 2:
114         expected_result_count = 0;
115         break;
116     case 1: /* Various events reported correctly */
117         expected_result_count = 5;
118         items[0].events = SSL_POLL_EVENT_OS;
119         expected_items[0].revents = SSL_POLL_EVENT_OS;
120 
121         expected_items[1].revents = SSL_POLL_EVENT_R;
122 
123         for (i = 0; i < 4; ++i) {
124             items[i + 1].events |= SSL_POLL_EVENT_W;
125             expected_items[i + 1].revents |= SSL_POLL_EVENT_W;
126         }
127 
128         break;
129     case 3: /* Blocking test */
130         expected_result_count = 1;
131         expected_items[1].revents = SSL_POLL_EVENT_R;
132 
133         p_timeout = &timeout;
134         timeout.tv_sec = 10;
135         timeout.tv_usec = 0;
136         break;
137     case 4: /* Listener test */
138         expected_result_count = 1;
139         items[5].events = SSL_POLL_EVENT_IC;
140         expected_items[5].revents = SSL_POLL_EVENT_IC;
141         break;
142     default:
143         goto err;
144     }
145 
146     /* Zero-timeout call. */
147     result_count = SIZE_MAX;
148     time_before = ossl_time_now();
149     if (!TEST_true(SSL_poll(items, OSSL_NELEM(items), sizeof(SSL_POLL_ITEM),
150             p_timeout, 0, &result_count)))
151         goto err;
152 
153     time_after = ossl_time_now();
154     if (!TEST_size_t_eq(result_count, expected_result_count))
155         goto err;
156 
157     for (i = 0; i < OSSL_NELEM(items); ++i)
158         if (!TEST_uint64_t_eq(items[i].revents, expected_items[i].revents))
159             goto err;
160 
161     /*
162      * The SSL_poll call for the blocking test definitely shouldn't have
163      * returned sooner than in 100ms.
164      */
165     if (i == 3 && !TEST_uint64_t_ge(ossl_time2ms(ossl_time_subtract(time_after, time_before)), 100))
166         goto err;
167 
168     ok = 1;
169 err:
170     return ok;
171 }
172 
173 DEF_SCRIPT(ssl_poll,
174     "test that SSL_poll is working")
175 {
176     size_t i;
177 
178     OP_SIMPLE_PAIR_CONN_ND();
179 
180     /* Setup streams */
181     OP_NEW_STREAM(C, C0, 0);
182     OP_WRITE_B(C0, "apple");
183 
184     OP_NEW_STREAM(C, C1, 0);
185     OP_WRITE_B(C1, "orange");
186 
187     OP_NEW_STREAM(C, C2, 0);
188     OP_WRITE_B(C2, "Strawberry");
189 
190     OP_NEW_STREAM(C, C3, 0);
191     OP_WRITE_B(C3, "sync");
192 
193     OP_ACCEPT_CONN_WAIT1_ND(L, La, 0);
194 
195     OP_ACCEPT_STREAM_WAIT(La, La0, 0);
196     OP_READ_EXPECT_B(La0, "apple");
197 
198     OP_ACCEPT_STREAM_WAIT(La, La1, 0);
199     OP_READ_EXPECT_B(La1, "orange");
200 
201     OP_ACCEPT_STREAM_WAIT(La, La2, 0);
202     OP_READ_EXPECT_B(La2, "Strawberry");
203 
204     OP_ACCEPT_STREAM_WAIT(La, La3, 0);
205     OP_READ_EXPECT_B(La3, "sync");
206 
207     for (i = 0; i <= 4; ++i) {
208         /* 0: Check nothing ready */
209         /* 1: Check that various events are reported correctly */
210         /* 2: Check nothing ready */
211         /* 3: Blocking call unblocked from child thread */
212         /* 4: Listener test */
213 
214         if (i == 1) {
215             OP_WRITE_B(C0, "orange");
216             OP_WRITE_B(C3, "sync");
217             OP_READ_EXPECT_B(La3, "sync");
218         } else if (i == 2) {
219             OP_READ_EXPECT_B(La0, "orange");
220         } else if (i == 3) {
221             OP_SPAWN_THREAD(ssl_poll_child);
222         } else if (i == 4) {
223             OP_NEW_SSL_C(Cb);
224             OP_SET_PEER_ADDR_FROM(Cb, L);
225             OP_CONNECT_WAIT(Cb);
226         }
227 
228         OP_SELECT_SSL(0, La);
229         OP_SELECT_SSL(1, La0);
230         OP_SELECT_SSL(2, La1);
231         OP_SELECT_SSL(3, La2);
232         OP_SELECT_SSL(4, La3);
233         OP_PUSH_U64(i);
234         OP_FUNC(ssl_poll_check);
235 
236         if (i == 3)
237             OP_READ_EXPECT_B(La0, "extra");
238 
239         if (i == 4) {
240             OP_ACCEPT_CONN_WAIT1_ND(L, Lb, 0);
241             OP_NEW_STREAM(Lb, Lb0, 0);
242             OP_WRITE_B(Lb0, "foo");
243             OP_READ_EXPECT_B(Cb, "foo");
244         }
245     }
246 }
247 
248 /*
249  * Test: poll_abort_blocking
250  * -------------------------
251  *
252  * SSL_poll(), when it has to block, registers each item's QUIC connection
253  * for cross-thread notification one item at a time (poll_translate() in
254  * ssl/rio/poll_immediate.c). If an item turns out to already be ready right
255  * as it is being registered, translation is aborted so the readout loop can
256  * retry instead of actually blocking. This exercises that abort path and
257  * checks that:
258  *
259  *   - SSL_poll() reports success rather than spuriously failing, and
260  *   - any items already registered before the abort have their blocking
261  *     section correctly left (i.e. no leak in the QUIC reactor's blocking
262  *     waiter count).
263  *
264  * The race between an item being registered and becoming ready is normally
265  * vanishingly narrow, so we use ossl_quic_poll_translate_test_step_cb (test
266  * instrumentation only, see ssl/rio/poll_builder.h) to deterministically
267  * make the second item ready immediately before poll_translate() processes
268  * it, while the first item is still mid-registration.
269  */
270 struct poll_abort_test_ctx {
271     SSL *peer_writer; /* write here to make target ready */
272     SSL *target;
273     uint64_t target_events;
274     size_t trigger_idx;
275     int made_ready; /* set by poll_abort_test_step_cb() on success */
276 };
277 
poll_abort_test_step_cb(size_t idx,void * arg)278 static void poll_abort_test_step_cb(size_t idx, void *arg)
279 {
280     struct poll_abort_test_ctx *ctx = arg;
281     uint64_t revents = 0;
282     int i;
283 
284     if (idx != ctx->trigger_idx)
285         return;
286 
287     if (SSL_write(ctx->peer_writer, "x", 1) != 1)
288         return;
289 
290     /* Force the data through synchronously so target is ready by the time we return. */
291     for (i = 0; i < 1000; ++i) {
292         if (!ossl_quic_conn_poll_events(ctx->target, ctx->target_events,
293                 /* do_tick = */ 1, &revents))
294             return;
295 
296         if (revents != 0) {
297             ctx->made_ready = 1;
298             return;
299         }
300 
301         OSSL_sleep(1);
302     }
303 }
304 
DEF_FUNC(check_poll_abort_blocking)305 DEF_FUNC(check_poll_abort_blocking)
306 {
307     int ok = 0;
308     SSL *C, *C0, *Cb0, *Lb0;
309     QUIC_CHANNEL *ch0;
310     QUIC_REACTOR *rtor0;
311     SSL_POLL_ITEM items[2] = { 0 };
312     size_t result_count = SIZE_MAX, waiters_before, waiters_after;
313     struct poll_abort_test_ctx ctx;
314     const struct timeval z_timeout = { 0 };
315 
316     /*
317      * C0 and Cb0 are streams of two independent client connections, and so
318      * belong to two independent QUIC_REACTORs. The bug being tested for does
319      * not actually require this: it reproduces just as well if all items
320      * share one reactor. What needs two reactors is poll_abort_test_step_cb()
321      * below, which forces Cb0 ready by ticking its reactor directly, on this
322      * thread, while C0's blocking section is still open. Doing that on C0's
323      * own (shared) reactor would deadlock: ossl_quic_reactor_tick() would see
324      * a nonzero cur_blocking_waiters left over from C0 and call
325      * rtor_notify_other_threads(), which waits on a condvar for some *other*
326      * thread to clear the notifier signal - a thread that doesn't exist here.
327      * Using Cb0's own, still-untouched reactor keeps that tick a no-op.
328      */
329     REQUIRE_SSL_4(C, C0, Cb0, Lb0);
330 
331     items[0].desc = SSL_as_poll_descriptor(C0);
332     items[0].events = SSL_POLL_EVENT_R;
333     items[1].desc = SSL_as_poll_descriptor(Cb0);
334     items[1].events = SSL_POLL_EVENT_R;
335 
336     /* Sanity check: nothing ready yet, so SSL_poll() will need to block. */
337     if (!TEST_true(SSL_poll(items, OSSL_NELEM(items), sizeof(SSL_POLL_ITEM),
338             &z_timeout, 0, &result_count))
339         || !TEST_size_t_eq(result_count, 0))
340         goto err;
341 
342     if (!TEST_ptr(ch0 = ossl_quic_conn_get_channel(C)))
343         goto err;
344     rtor0 = ossl_quic_channel_get_reactor(ch0);
345     waiters_before = rtor0->cur_blocking_waiters;
346 
347     ctx.peer_writer = Lb0;
348     ctx.target = Cb0;
349     ctx.target_events = items[1].events;
350     ctx.trigger_idx = 1;
351     ctx.made_ready = 0;
352 
353     ossl_quic_poll_translate_test_step_cb_arg = &ctx;
354     ossl_quic_poll_translate_test_step_cb = poll_abort_test_step_cb;
355 
356     result_count = SIZE_MAX;
357     /*
358      * No timeout: if the abort_blocking case were instead to actually block,
359      * this call would hang forever rather than fail fast.
360      */
361     ok = TEST_true(SSL_poll(items, OSSL_NELEM(items), sizeof(SSL_POLL_ITEM),
362         NULL, 0, &result_count));
363 
364     ossl_quic_poll_translate_test_step_cb = NULL;
365     ossl_quic_poll_translate_test_step_cb_arg = NULL;
366 
367     if (!ok)
368         goto err;
369 
370     ok = 0;
371     if (!TEST_true(ctx.made_ready)
372         || !TEST_size_t_ge(result_count, 1)
373         || !TEST_true((items[1].revents & SSL_POLL_EVENT_R) != 0))
374         goto err;
375 
376     /* The first item's blocking-section entry must have been balanced. */
377     waiters_after = rtor0->cur_blocking_waiters;
378     if (!TEST_size_t_eq(waiters_after, waiters_before))
379         goto err;
380 
381     ok = 1;
382 err:
383     ossl_quic_poll_translate_test_step_cb = NULL;
384     ossl_quic_poll_translate_test_step_cb_arg = NULL;
385     return ok;
386 }
387 
388 DEF_SCRIPT(poll_abort_blocking,
389     "test that SSL_poll() correctly handles an item becoming ready while blocking is being set up")
390 {
391     OP_SIMPLE_PAIR_CONN_ND();
392 
393     OP_NEW_STREAM(C, C0, 0);
394     OP_WRITE_B(C0, "probe0");
395 
396     OP_ACCEPT_CONN_WAIT1_ND(L, La, 0);
397     OP_ACCEPT_STREAM_WAIT(La, La0, 0);
398     OP_READ_EXPECT_B(La0, "probe0");
399 
400     /* A second, independent client connection to the same listener. */
401     OP_NEW_SSL_C(Cb);
402     OP_SET_PEER_ADDR_FROM(Cb, L);
403     OP_CONNECT_WAIT(Cb);
404     OP_SET_DEFAULT_STREAM_MODE(Cb, SSL_DEFAULT_STREAM_MODE_NONE);
405 
406     OP_NEW_STREAM(Cb, Cb0, 0);
407     OP_WRITE_B(Cb0, "probe1");
408 
409     OP_ACCEPT_CONN_WAIT1_ND(L, Lb, 0);
410     OP_ACCEPT_STREAM_WAIT(Lb, Lb0, 0);
411     OP_READ_EXPECT_B(Lb0, "probe1");
412 
413     OP_SELECT_SSL(0, C);
414     OP_SELECT_SSL(1, C0);
415     OP_SELECT_SSL(2, Cb0);
416     OP_SELECT_SSL(3, Lb0);
417     OP_FUNC(check_poll_abort_blocking);
418 }
419 
DEF_FUNC(check_writeable)420 DEF_FUNC(check_writeable)
421 {
422     int ok = 0;
423     SSL *ssl;
424     SSL_POLL_ITEM item;
425     size_t result_count = 0;
426     uint64_t expect;
427     const struct timeval z_timeout = { 0 }, *p_timeout = &z_timeout;
428 
429     F_POP(expect);
430     REQUIRE_SSL(ssl);
431 
432     item.desc = SSL_as_poll_descriptor(ssl);
433     item.events = SSL_POLL_EVENT_W;
434     item.revents = 0;
435 
436     /* Zero-timeout call. */
437     result_count = SIZE_MAX;
438     if (!TEST_true(SSL_poll(&item, 1, sizeof(SSL_POLL_ITEM),
439             p_timeout, 0, &result_count)))
440         goto err;
441 
442     ok = (!!(item.revents & SSL_POLL_EVENT_W) == expect);
443 
444 err:
445     return ok;
446 }
447 
448 DEF_SCRIPT(check_cwm, "check stream obeys cwm")
449 {
450     OP_SIMPLE_PAIR_CONN();
451 
452     /* Create the initial stream by writing some data */
453     OP_WRITE_RAND(C, 1024);
454 
455     /* We should be writeable at the start */
456     OP_PUSH_U64(1);
457     OP_SELECT_SSL(0, C);
458     OP_FUNC(check_writeable);
459 
460     /* Default stream cwm is 512k (we already sent 1k). Consume all the rest */
461     OP_WRITE_RAND(C, 511 * 1024);
462 
463     /* Confirm we are no longer writeable */
464     OP_PUSH_U64(0);
465     OP_SELECT_SSL(0, C);
466     OP_FUNC(check_writeable);
467 
468     /* We now expect writes to fail */
469     OP_WRITE_FAIL(C);
470 }
471 
472 struct mutcbk_ctx {
473     QUIC_PKT_HDR mutctx_qhdrin;
474     OSSL_QTX_IOVEC mutctx_iov;
475     const unsigned char *mutctx_inject;
476     size_t mutctx_inject_sz;
477     int mutctx_done;
478 };
479 
mutcbk_inject_frames(const QUIC_PKT_HDR * hdrin,const OSSL_QTX_IOVEC * iovecin,size_t numin,QUIC_PKT_HDR ** hdrout,const OSSL_QTX_IOVEC ** iovecout,size_t * numout,void * arg)480 static int mutcbk_inject_frames(const QUIC_PKT_HDR *hdrin,
481     const OSSL_QTX_IOVEC *iovecin, size_t numin, QUIC_PKT_HDR **hdrout,
482     const OSSL_QTX_IOVEC **iovecout, size_t *numout, void *arg)
483 {
484     struct mutcbk_ctx *mutctx = (struct mutcbk_ctx *)arg;
485     size_t i;
486     size_t grow_allowance = 1200; /* QUIC_MIN_INITIAL_DGRAM_LEN */
487     size_t bufsz = 0;
488     char *buf;
489 
490     /*
491      * make injection callback a one shot event,
492      * callback is invoked for every packet we
493      * want to modify only one packet here. Returning 0 tells the QTX the
494      * packet send itself failed (tearing down the connection), so once
495      * we're done mutating we must pass subsequent packets through
496      * unmodified instead.
497      */
498     if (mutctx->mutctx_done) {
499         *hdrout = (QUIC_PKT_HDR *)hdrin;
500         *iovecout = iovecin;
501         *numout = numin;
502         return 1;
503     }
504 
505     mutctx->mutctx_done = 1;
506 
507     for (i = 0; i < numin; i++)
508         bufsz += iovecin[i].buf_len;
509 
510     mutctx->mutctx_iov.buf_len = bufsz; /* keeps old size */
511     grow_allowance -= (bufsz < grow_allowance) ? bufsz : grow_allowance;
512     /* AEAD tag (16 bytes) + long header (14 bytes) */
513     grow_allowance -= (30 < grow_allowance) ? 30 : grow_allowance;
514 
515     grow_allowance -= (hdrin->dst_conn_id.id_len < grow_allowance) ? hdrin->dst_conn_id.id_len : grow_allowance;
516     grow_allowance -= (hdrin->src_conn_id.id_len < grow_allowance) ? hdrin->src_conn_id.id_len : grow_allowance;
517 
518     if (grow_allowance == 0) {
519         TEST_info("mutcbk_inject_frames() not enough space to inject");
520         return 0;
521     }
522     bufsz += grow_allowance;
523 
524     /* discard const */
525     OPENSSL_free((char *)mutctx->mutctx_iov.buf);
526     mutctx->mutctx_iov.buf = OPENSSL_malloc(bufsz);
527     /* discard const */
528     buf = (char *)mutctx->mutctx_iov.buf;
529     if (buf == NULL) {
530         TEST_info("mutcbk_inject_frames() OPENSSL_malloc() failed");
531         return 0;
532     }
533 
534     for (i = 0; i < numin; i++) {
535         memcpy(buf, iovecin[i].buf, iovecin[i].buf_len);
536         buf += iovecin[i].buf_len;
537     }
538 
539     /* discard const */
540     buf = (char *)mutctx->mutctx_iov.buf;
541     if (mutctx->mutctx_inject != NULL) {
542         memmove(buf + mutctx->mutctx_inject_sz, buf,
543             mutctx->mutctx_iov.buf_len);
544         memcpy(buf, mutctx->mutctx_inject, mutctx->mutctx_inject_sz);
545     }
546     /*
547      * perhaps needed to have not looked at yet
548      */
549     mutctx->mutctx_qhdrin = *hdrin;
550     *hdrout = &mutctx->mutctx_qhdrin;
551     mutctx->mutctx_iov.buf_len += mutctx->mutctx_inject_sz;
552     *iovecout = &mutctx->mutctx_iov;
553     *numout = 1;
554 
555     return 1;
556 }
557 
mutcbk_finish_injecct_frames(void * arg)558 static void mutcbk_finish_injecct_frames(void *arg)
559 {
560     struct mutcbk_ctx *mutctx = (struct mutcbk_ctx *)arg;
561 
562     OPENSSL_free((char *)mutctx->mutctx_iov.buf);
563     mutctx->mutctx_iov.buf = NULL;
564 }
565 
566 /* 16 path challenge frames */
567 #define PATH_CHALLENGE_FRAMES \
568     "\x1a"                    \
569     "ABCDEFGH"                \
570     "\x1a"                    \
571     "ABCDEFGH"                \
572     "\x1a"                    \
573     "ABCDEFGH"                \
574     "\x1a"                    \
575     "ABCDEFGH"                \
576     "\x1a"                    \
577     "ABCDEFGH"                \
578     "\x1a"                    \
579     "ABCDEFGH"                \
580     "\x1a"                    \
581     "ABCDEFGH"                \
582     "\x1a"                    \
583     "ABCDEFGH"                \
584     "\x1a"                    \
585     "ABCDEFGH"                \
586     "\x1a"                    \
587     "ABCDEFGH"                \
588     "\x1a"                    \
589     "ABCDEFGH"                \
590     "\x1a"                    \
591     "ABCDEFGH"                \
592     "\x1a"                    \
593     "ABCDEFGH"                \
594     "\x1a"                    \
595     "ABCDEFGH"                \
596     "\x1a"                    \
597     "ABCDEFGH"                \
598     "\x1a"                    \
599     "ABCDEFGH"
600 
DEF_FUNC(mount_flood)601 DEF_FUNC(mount_flood)
602 {
603     int ok = 0;
604     SSL *ssl;
605     QUIC_CHANNEL *ch;
606     static struct mutcbk_ctx mutctx = { 0 };
607     static const unsigned char *inject_frames = (const unsigned char *)PATH_CHALLENGE_FRAMES;
608 
609     mutctx.mutctx_inject = inject_frames;
610     mutctx.mutctx_inject_sz = sizeof(PATH_CHALLENGE_FRAMES) - 1;
611     REQUIRE_SSL(ssl);
612     ch = ossl_quic_conn_get_channel(ssl);
613     if (!TEST_ptr(ch))
614         goto err;
615 
616     if (!TEST_true(ossl_quic_channel_set_mutator(ch, mutcbk_inject_frames,
617             mutcbk_finish_injecct_frames, &mutctx)))
618         goto err;
619     ok = 1;
620 err:
621     return ok;
622 }
623 
DEF_FUNC(check_flood_stats)624 DEF_FUNC(check_flood_stats)
625 {
626     int ok = 0;
627     SSL *ssl;
628     QUIC_CHANNEL *ch;
629     uint64_t path_response_count;
630     uint64_t path_challenge_count;
631 
632     REQUIRE_SSL(ssl);
633     ch = ossl_quic_conn_get_channel(ssl);
634     if (!TEST_ptr(ch))
635         goto err;
636 
637     path_challenge_count = ossl_quic_channel_get_path_challenge_count(ch);
638     path_response_count = ossl_quic_channel_get_path_response_count(ch);
639 
640     /*
641      * The flood is delivered over a real socket and processed by the
642      * connection's assist thread asynchronously, so give it a chance to
643      * catch up rather than failing on the first observation.
644      */
645     if (path_challenge_count < 16 || path_response_count < 1)
646         F_SPIN_AGAIN();
647 
648     if (!TEST_uint64_t_eq(path_challenge_count, 16))
649         goto err;
650     if (!TEST_uint64_t_eq(path_response_count, 1))
651         goto err;
652 
653     ok = 1;
654 err:
655     return ok;
656 }
657 
658 DEF_SCRIPT(check_pc_flood, "check path challenge flood")
659 {
660     OP_SIMPLE_PAIR_CONN();
661     OP_SELECT_SSL(0, C);
662     OP_FUNC(mount_flood);
663     OP_ACCEPT_CONN_WAIT(L, S, 0);
664     OP_WRITE_B(C, "attack");
665     OP_SELECT_SSL(0, S);
666     OP_FUNC(check_flood_stats);
667 }
668 
669 /*
670  * Test to make sure that SSL_accept_connection returns the same ssl object
671  * that is used in the various TLS callbacks
672  *
673  * Unlike TCP, QUIC processes new connections independently from their
674  * acceptance, and so we need to pre-allocate tls objects to return during
675  * connection acceptance via the user_ssl.  This is just a quic test to validate
676  * that:
677  * 1) The new callback to inform the user of a new pending ssl acceptance works
678  *    properly
679  * 2) That the object returned from SSL_accept_connection matches the one passed
680  *    to various callbacks
681  *
682  * It would be better as its own test, but currently the tserver used in the
683  * other quic_tests doesn't actually accept connections (it pre-creates them
684  * and fixes them up in place), so testing there is not feasible at the moment
685  *
686  * For details on this issue see:
687  * https://github.com/openssl/project/issues/918
688  */
689 static SSL *pending_ssl_obj = NULL;
690 static SSL *client_hello_ssl_obj = NULL;
691 static int check_pending_match = 0;
692 static int pending_cb_called = 0;
693 static int hello_cb_called = 0;
694 
new_pending_cb(SSL_CTX * ctx,SSL * new_ssl,void * arg)695 static int new_pending_cb(SSL_CTX *ctx, SSL *new_ssl, void *arg)
696 {
697     pending_ssl_obj = new_ssl;
698     pending_cb_called = 1;
699     return 1;
700 }
701 
client_hello_cb(SSL * s,int * al,void * arg)702 static int client_hello_cb(SSL *s, int *al, void *arg)
703 {
704     client_hello_ssl_obj = s;
705     hello_cb_called = 1;
706     return 1;
707 }
708 
DEF_FUNC(init_pending_test)709 DEF_FUNC(init_pending_test)
710 {
711     pending_ssl_obj = NULL;
712     client_hello_ssl_obj = NULL;
713     check_pending_match = 0;
714     pending_cb_called = 0;
715     hello_cb_called = 0;
716 
717     return 1;
718 }
719 
DEF_FUNC(check_pending)720 DEF_FUNC(check_pending)
721 {
722     int ok = 0;
723     SSL *conn;
724 
725     REQUIRE_SSL(conn);
726 
727     if (check_pending_match) {
728         if (!TEST_true(pending_cb_called))
729             goto err;
730 
731         if (!TEST_true(hello_cb_called))
732             goto err;
733 
734         if (!TEST_ptr_eq(pending_ssl_obj, client_hello_ssl_obj))
735             goto err;
736 
737         if (!TEST_ptr_eq(pending_ssl_obj, conn))
738             goto err;
739 
740         pending_ssl_obj = client_hello_ssl_obj = NULL;
741         check_pending_match = 0;
742         pending_cb_called = hello_cb_called = 0;
743     }
744 
745     ok = 1;
746 err:
747     return ok;
748 }
749 
DEF_FUNC(new_listener)750 DEF_FUNC(new_listener)
751 {
752     int ok = 0;
753     SSL_CTX *ctx = NULL;
754     SSL *listener;
755     const char *name;
756 
757     F_POP(name);
758 
759     if (!TEST_ptr(ctx = SSL_CTX_new(OSSL_QUIC_server_method())))
760         goto err;
761 
762 #if defined(OPENSSL_THREADS)
763     if (!TEST_true(SSL_CTX_set_domain_flags(ctx,
764             SSL_DOMAIN_FLAG_MULTI_THREAD
765                 | SSL_DOMAIN_FLAG_BLOCKING)))
766         goto err;
767 #endif
768 
769     if (!TEST_true(ssl_ctx_configure(ctx, 1)))
770         goto err;
771 
772     SSL_CTX_set_new_pending_conn_cb(ctx, new_pending_cb, NULL);
773     SSL_CTX_set_client_hello_cb(ctx, client_hello_cb, NULL);
774     check_pending_match = 1;
775     if (!TEST_ptr(listener = SSL_new_listener(ctx, 0)))
776         goto err;
777 
778     if (!TEST_true(ssl_attach_bio_dgram(listener, 0, NULL))) {
779         SSL_free(listener);
780         goto err;
781     }
782 
783     if (!TEST_true(RADIX_PROCESS_set_ssl(RP(), name, listener))) {
784         SSL_free(listener);
785         goto err;
786     }
787 
788     ok = 1;
789 err:
790     /* SSL object will hold ref, we don't need it */
791     SSL_CTX_free(ctx);
792     return ok;
793 }
794 
795 DEF_SCRIPT(check_ctx_cbks, "Check new_pending and client_hello callbacks")
796 {
797     OP_FUNC(init_pending_test);
798     OP_PUSH_PZ("L");
799     OP_FUNC(new_listener);
800     OP_LISTEN(L);
801     OP_NEW_SSL_C(C);
802     OP_SET_PEER_ADDR_FROM(C, L);
803     OP_CONNECT_WAIT(C);
804     OP_ACCEPT_CONN_WAIT(L, S, 0);
805     OP_SELECT_SSL(0, S);
806     OP_FUNC(check_pending);
807 }
808 
809 /*
810  * List of Test Scripts
811  * ============================================================================
812  */
813 static SCRIPT_INFO *const scripts[] = {
814     USE(simple_conn),
815     USE(simple_thread),
816     USE(ssl_poll),
817     USE(poll_abort_blocking),
818     USE(check_cwm),
819     USE(check_pc_flood),
820     USE(check_ctx_cbks),
821 };
822