Coverage Report

Created: 2026-08-31 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/ssl/rio/poll_immediate.c
Line
Count
Source
1
/*
2
 * Copyright 2024-2025 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/common.h"
11
#include "internal/quic_ssl.h"
12
#include "internal/quic_reactor_wait_ctx.h"
13
#include "internal/ssl_unwrap.h"
14
#include <openssl/ssl.h>
15
#include <openssl/err.h>
16
#include "../ssl_local.h"
17
#include "poll_builder.h"
18
19
#ifdef OPENSSL_NO_QUIC
20
/* Stub type when QUIC is disabled so function signatures remain consistent */
21
typedef int QUIC_REACTOR_WAIT_CTX;
22
#endif
23
24
#if defined(_AIX)
25
/*
26
 * Some versions of AIX define macros for events and revents for use when
27
 * accessing pollfd structures (see Github issue #24236). That interferes
28
 * with our use of these names here. We simply undef them.
29
 */
30
#undef revents
31
#undef events
32
#endif
33
34
#define ITEM_N(items, stride, n) \
35
0
    (*(SSL_POLL_ITEM *)((char *)(items) + (n) * (stride)))
36
37
#define FAIL_FROM(n)                              \
38
0
    do {                                          \
39
0
        size_t j;                                 \
40
0
                                                  \
41
0
        for (j = (n); j < num_items; ++j)         \
42
0
            ITEM_N(items, stride, j).revents = 0; \
43
0
                                                  \
44
0
        ok = 0;                                   \
45
0
        goto out;                                 \
46
0
    } while (0)
47
48
#define FAIL_ITEM(idx)                                          \
49
0
    do {                                                        \
50
0
        size_t idx_ = (idx);                                    \
51
0
                                                                \
52
0
        ITEM_N(items, stride, idx_).revents = SSL_POLL_EVENT_F; \
53
0
        ++result_count;                                         \
54
0
        FAIL_FROM(idx_ + 1);                                    \
55
0
    } while (0)
56
57
#ifndef OPENSSL_NO_QUIC
58
/*
59
 * Test instrumentation only; see poll_builder.h. Always NULL in production
60
 * use.
61
 */
62
void (*ossl_quic_poll_translate_test_step_cb)(size_t idx, void *arg) = NULL;
63
void *ossl_quic_poll_translate_test_step_cb_arg = NULL;
64
65
static int poll_translate_ssl_quic(SSL *ssl,
66
    QUIC_REACTOR_WAIT_CTX *wctx,
67
    RIO_POLL_BUILDER *rpb,
68
    uint64_t events,
69
    int *abort_blocking)
70
0
{
71
0
    BIO_POLL_DESCRIPTOR rd, wd;
72
0
    int fd1 = -1, fd2 = -1, fd_nfy = -1;
73
0
    int fd1_r = 0, fd1_w = 0, fd2_w = 0;
74
75
0
    if (SSL_net_read_desired(ssl)) {
76
0
        if (!SSL_get_rpoll_descriptor(ssl, &rd)) {
77
0
            ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
78
0
                "SSL_poll requires the network BIOs underlying "
79
0
                "a QUIC SSL object provide poll descriptors");
80
0
            return 0;
81
0
        }
82
83
0
        if (rd.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) {
84
0
            ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
85
0
                "SSL_poll requires the poll descriptors of the "
86
0
                "network BIOs underlying a QUIC SSL object be "
87
0
                "of socket type");
88
0
            return 0;
89
0
        }
90
91
0
        fd1 = rd.value.fd;
92
0
        fd1_r = 1;
93
0
    }
94
95
0
    if (SSL_net_write_desired(ssl)) {
96
0
        if (!SSL_get_wpoll_descriptor(ssl, &wd)) {
97
0
            ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
98
0
                "SSL_poll requires the network BIOs underlying "
99
0
                "a QUIC SSL object provide poll descriptors");
100
0
            return 0;
101
0
        }
102
103
0
        if (wd.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) {
104
0
            ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
105
0
                "SSL_poll requires the poll descriptors of the "
106
0
                "network BIOs underlying a QUIC SSL object be "
107
0
                "of socket type");
108
0
            return 0;
109
0
        }
110
111
0
        fd2 = wd.value.fd;
112
0
        fd2_w = 1;
113
0
    }
114
115
0
    if (fd2 == fd1) {
116
0
        fd2 = -1;
117
0
        fd1_w = fd2_w;
118
0
    }
119
120
0
    if (fd1 != -1)
121
0
        if (!ossl_rio_poll_builder_add_fd(rpb, fd1, fd1_r, fd1_w))
122
0
            return 0;
123
124
0
    if (fd2 != -1 && fd2_w)
125
0
        if (!ossl_rio_poll_builder_add_fd(rpb, fd2, /*r = */ 0, fd2_w))
126
0
            return 0;
127
128
    /*
129
     * Add the notifier FD for the QUIC domain this SSL object is a part of (if
130
     * there is one). This ensures we get woken up if another thread calls into
131
     * that QUIC domain and some readiness event relevant to the SSL_poll call
132
     * on this thread arises without the underlying network socket ever becoming
133
     * readable.
134
     */
135
0
    fd_nfy = ossl_quic_get_notifier_fd(ssl);
136
0
    if (fd_nfy != -1) {
137
0
        uint64_t revents = 0;
138
139
0
        if (!ossl_rio_poll_builder_add_fd(rpb, fd_nfy, /*r = */ 1, /*w = */ 0))
140
0
            return 0;
141
142
        /* Tell QUIC domain we need to receive notifications. */
143
0
        ossl_quic_enter_blocking_section(ssl, wctx);
144
145
        /*
146
         * Only after the above call returns is it guaranteed that any readiness
147
         * events will cause the above notifier to become readable. Therefore,
148
         * it is possible the object became ready after our initial
149
         * poll_readout() call (before we determined that nothing was ready and
150
         * we needed to block). We now need to do another readout, in which case
151
         * blocking is to be aborted.
152
         */
153
0
        if (!ossl_quic_conn_poll_events(ssl, events, /*do_tick = */ 0, &revents)) {
154
0
            ossl_quic_leave_blocking_section(ssl, wctx);
155
0
            return 0;
156
0
        }
157
158
0
        if (revents != 0) {
159
0
            ossl_quic_leave_blocking_section(ssl, wctx);
160
0
            *abort_blocking = 1;
161
0
            return 1;
162
0
        }
163
0
    }
164
165
0
    return 1;
166
0
}
167
168
static void postpoll_translation_cleanup_ssl_quic(SSL *ssl,
169
    QUIC_REACTOR_WAIT_CTX *wctx)
170
0
{
171
0
    if (ossl_quic_get_notifier_fd(ssl) != -1)
172
0
        ossl_quic_leave_blocking_section(ssl, wctx);
173
0
}
174
#endif /* OPENSSL_NO_QUIC */
175
176
#ifndef OPENSSL_NO_DTLS
177
static int poll_translate_ssl_dtls_listener(SSL *ssl,
178
    RIO_POLL_BUILDER *rpb,
179
    uint64_t events,
180
    int *abort_blocking)
181
0
{
182
0
    BIO *rbio;
183
0
    BIO_POLL_DESCRIPTOR desc;
184
0
    DTLS_LISTENER *dl = (DTLS_LISTENER *)ssl;
185
0
    uint64_t revents = 0;
186
0
    int nfd;
187
188
0
    rbio = SSL_get_rbio(ssl);
189
0
    if (rbio == NULL)
190
0
        return 0;
191
192
0
    if (!BIO_get_rpoll_descriptor(rbio, &desc)
193
0
        || desc.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) {
194
0
        ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
195
0
            "DTLS listener requires a socket BIO for blocking poll");
196
0
        return 0;
197
0
    }
198
199
    /*
200
     * Watch the socket for readability whatever was asked for. Every event a
201
     * listener reports is ultimately driven by a datagram arriving, both an
202
     * incoming connection and data pending on the listener itself, so there is
203
     * no event for which this is the wrong thing to wait on. events is
204
     * therefore only consulted for the readiness re-check below.
205
     */
206
0
    if (!ossl_rio_poll_builder_add_fd(rpb, desc.value.fd, /*r=*/1, /*w=*/0))
207
0
        return 0;
208
209
    /*
210
     * Add the notifier FD for the DTLS listener (if multi-threaded mode is
211
     * enabled). Another thread may queue an incoming connection for us, or
212
     * demux data to one of our connections, without the underlying network
213
     * socket ever becoming readable from our perspective.
214
     */
215
0
    if (dl->have_notifier) {
216
0
        nfd = ossl_rio_notifier_as_fd(&dl->notifier);
217
0
        if (nfd != -1) {
218
0
            if (!ossl_rio_poll_builder_add_fd(rpb, nfd, /*r=*/1, /*w=*/0))
219
0
                return 0;
220
221
            /* Tell the listener we need to receive notifications. */
222
0
            ossl_dtls_listener_enter_blocking_section(ssl);
223
224
            /*
225
             * Only after the above call returns is it guaranteed that any
226
             * readiness events will cause the notifier to become readable.
227
             * Therefore it is possible the listener became ready after the
228
             * readout which decided we needed to block. Re-check now.
229
             */
230
0
            if (!ossl_dtls_listener_poll_events(ssl, events, /*do_tick=*/0,
231
0
                    &revents)) {
232
0
                ossl_dtls_listener_leave_blocking_section(ssl);
233
0
                return 0;
234
0
            }
235
236
0
            if (revents != 0) {
237
0
                ossl_dtls_listener_leave_blocking_section(ssl);
238
0
                *abort_blocking = 1;
239
0
                return 1;
240
0
            }
241
0
        }
242
0
    }
243
244
0
    return 1;
245
0
}
246
247
static int poll_translate_ssl_dtls_conn(SSL *ssl,
248
    RIO_POLL_BUILDER *rpb,
249
    uint64_t events,
250
    int *abort_blocking)
251
0
{
252
0
    BIO *rbio, *wbio;
253
0
    BIO_POLL_DESCRIPTOR rdesc, wdesc;
254
0
    int rfd = -1, wfd = -1, nfd = -1;
255
0
    SSL_CONNECTION *sc;
256
0
    DTLS_LISTENER *dl = NULL;
257
0
    int has_pending;
258
259
0
    sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
260
261
0
    if (sc != NULL && sc->d1 != NULL && sc->d1->listener != NULL)
262
0
        dl = (DTLS_LISTENER *)sc->d1->listener;
263
264
0
    if ((events & SSL_POLL_EVENT_R) != 0) {
265
0
        rbio = SSL_get_rbio(ssl);
266
267
0
        if (rbio == NULL && dl != NULL) {
268
            /*
269
             * Listener-based DTLS connection. First, pump the listener's
270
             * demux to ensure any pending datagrams on the socket are
271
             * routed to their respective connection URXE queues.
272
             */
273
0
            ossl_dtls_tick(dl);
274
275
            /*
276
             * Now check the URXE buffer. If data has been demuxed into
277
             * this connection's receive queue, abort blocking immediately -
278
             * there is no need to wait on the socket FD.
279
             */
280
0
            if (sc->d1->rx != NULL) {
281
0
                ossl_crypto_mutex_lock(sc->d1->rx->mutex);
282
0
                has_pending = !ossl_list_urxe_is_empty(&sc->d1->rx->urxe_pending);
283
0
                ossl_crypto_mutex_unlock(sc->d1->rx->mutex);
284
0
                if (has_pending) {
285
0
                    *abort_blocking = 1;
286
0
                    return 1;
287
0
                }
288
0
            }
289
290
            /*
291
             * Add the notifier FD for the DTLS listener (if multi-threaded
292
             * mode is enabled). This ensures we get woken up if another thread
293
             * demuxes data to this connection's URXE queue without the
294
             * underlying network socket ever becoming readable from our
295
             * perspective.
296
             */
297
0
            if (dl->have_notifier) {
298
0
                nfd = ossl_rio_notifier_as_fd(&dl->notifier);
299
0
                if (nfd != -1) {
300
0
                    if (!ossl_rio_poll_builder_add_fd(rpb, nfd, /*r=*/1, /*w=*/0))
301
0
                        return 0;
302
303
                    /* Tell listener we need to receive notifications. */
304
0
                    ossl_dtls_listener_enter_blocking_section(sc->d1->listener);
305
306
                    /*
307
                     * Only after the above call returns is it guaranteed that
308
                     * any readiness events will cause the notifier to become
309
                     * readable. Therefore, it is possible data was demuxed to
310
                     * our URXE queue after our initial check above but before
311
                     * we entered the blocking section. Re-check now.
312
                     */
313
0
                    if (sc->d1->rx != NULL) {
314
0
                        ossl_crypto_mutex_lock(sc->d1->rx->mutex);
315
0
                        has_pending = !ossl_list_urxe_is_empty(&sc->d1->rx->urxe_pending);
316
0
                        ossl_crypto_mutex_unlock(sc->d1->rx->mutex);
317
0
                        if (has_pending) {
318
0
                            ossl_dtls_listener_leave_blocking_section(sc->d1->listener);
319
0
                            *abort_blocking = 1;
320
0
                            return 1;
321
0
                        }
322
0
                    }
323
0
                }
324
0
            }
325
326
            /*
327
             * URXE buffer is empty. Fall back to the listener's rbio so the
328
             * OS-level poll() wakes us up when the shared socket becomes
329
             * readable and new datagrams may arrive.
330
             */
331
0
            rbio = SSL_get_rbio(sc->d1->listener);
332
0
        }
333
334
0
        if (rbio != NULL) {
335
0
            if (BIO_get_rpoll_descriptor(rbio, &rdesc)
336
0
                && rdesc.type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD)
337
0
                rfd = rdesc.value.fd;
338
0
        }
339
0
    }
340
341
0
    if ((events & SSL_POLL_EVENT_W) != 0) {
342
0
        wbio = SSL_get_wbio(ssl);
343
0
        if (wbio != NULL) {
344
0
            if (BIO_get_wpoll_descriptor(wbio, &wdesc)
345
0
                && wdesc.type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD)
346
0
                wfd = wdesc.value.fd;
347
0
        }
348
0
    }
349
350
    /* If same FD for read and write, combine them */
351
0
    if (rfd != -1 && wfd == rfd) {
352
0
        if (!ossl_rio_poll_builder_add_fd(rpb, rfd, /*r=*/1, /*w=*/1))
353
0
            return 0;
354
0
    } else {
355
0
        if (rfd != -1)
356
0
            if (!ossl_rio_poll_builder_add_fd(rpb, rfd, /*r=*/1, /*w=*/0))
357
0
                return 0;
358
0
        if (wfd != -1)
359
0
            if (!ossl_rio_poll_builder_add_fd(rpb, wfd, /*r=*/0, /*w=*/1))
360
0
                return 0;
361
0
    }
362
363
0
    return 1;
364
0
}
365
366
static void postpoll_translation_cleanup_ssl_dtls_listener(SSL *ssl)
367
0
{
368
0
    DTLS_LISTENER *dl = (DTLS_LISTENER *)ssl;
369
370
    /* Need to mirror the enter blocking section call */
371
0
    if (dl->have_notifier && ossl_rio_notifier_as_fd(&dl->notifier) != -1)
372
0
        ossl_dtls_listener_leave_blocking_section(ssl);
373
0
}
374
375
static void postpoll_translation_cleanup_ssl_dtls_conn(SSL *ssl, uint64_t events)
376
0
{
377
0
    SSL_CONNECTION *sc;
378
0
    DTLS_LISTENER *dl;
379
380
    /*
381
     * We only enter blocking section when read events are requested.
382
     * Don't call leave if we never entered.
383
     */
384
0
    if ((events & SSL_POLL_EVENT_R) == 0)
385
0
        return;
386
387
0
    sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
388
0
    if (sc == NULL || sc->d1 == NULL || sc->d1->listener == NULL)
389
0
        return;
390
391
    /* Need to mirror the enter blocking section call */
392
0
    if (SSL_get_rbio(ssl) != NULL)
393
0
        return;
394
395
0
    dl = (DTLS_LISTENER *)sc->d1->listener;
396
0
    if (dl->have_notifier && ossl_rio_notifier_as_fd(&dl->notifier) != -1)
397
0
        ossl_dtls_listener_leave_blocking_section(sc->d1->listener);
398
0
}
399
#endif /* OPENSSL_NO_DTLS */
400
401
#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS)
402
static void postpoll_translation_cleanup(SSL_POLL_ITEM *items,
403
    size_t num_items,
404
    size_t stride,
405
    ossl_unused QUIC_REACTOR_WAIT_CTX *wctx)
406
0
{
407
0
    SSL_POLL_ITEM *item;
408
0
    SSL *ssl;
409
0
    size_t i;
410
411
0
    for (i = 0; i < num_items; ++i) {
412
0
        item = &ITEM_N(items, stride, i);
413
414
0
        switch (item->desc.type) {
415
0
        case BIO_POLL_DESCRIPTOR_TYPE_SSL:
416
0
            ssl = item->desc.value.ssl;
417
0
            if (ssl == NULL)
418
0
                break;
419
420
0
            switch (ssl->type) {
421
0
#ifndef OPENSSL_NO_QUIC
422
0
            case SSL_TYPE_QUIC_LISTENER:
423
0
            case SSL_TYPE_QUIC_CONNECTION:
424
0
            case SSL_TYPE_QUIC_XSO:
425
0
                postpoll_translation_cleanup_ssl_quic(ssl, wctx);
426
0
                break;
427
0
#endif
428
429
0
#ifndef OPENSSL_NO_DTLS
430
0
            case SSL_TYPE_DTLS_LISTENER:
431
0
                postpoll_translation_cleanup_ssl_dtls_listener(ssl);
432
0
                break;
433
0
            case SSL_TYPE_SSL_CONNECTION:
434
0
                if (SSL_is_dtls(ssl))
435
0
                    postpoll_translation_cleanup_ssl_dtls_conn(ssl, item->events);
436
0
                break;
437
0
#endif
438
439
0
            default:
440
0
                break;
441
0
            }
442
0
            break;
443
0
        default:
444
0
            break;
445
0
        }
446
0
    }
447
0
}
448
449
static int poll_translate(SSL_POLL_ITEM *items,
450
    size_t num_items,
451
    size_t stride,
452
    ossl_unused QUIC_REACTOR_WAIT_CTX *wctx,
453
    RIO_POLL_BUILDER *rpb,
454
    OSSL_TIME *p_earliest_wakeup_deadline,
455
    int *abort_blocking,
456
    int bound_by_event_timeout,
457
    size_t *p_result_count)
458
0
{
459
0
    int ok = 1;
460
0
    SSL_POLL_ITEM *item;
461
0
    size_t result_count = 0;
462
0
    SSL *ssl;
463
0
    OSSL_TIME earliest_wakeup_deadline = ossl_time_infinite();
464
0
#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS)
465
0
    struct timeval timeout;
466
0
    int is_infinite = 0;
467
0
#endif
468
0
    size_t i;
469
470
0
    for (i = 0; i < num_items; ++i) {
471
0
        item = &ITEM_N(items, stride, i);
472
473
0
#ifndef OPENSSL_NO_QUIC
474
0
        if (ossl_quic_poll_translate_test_step_cb != NULL)
475
0
            ossl_quic_poll_translate_test_step_cb(i,
476
0
                ossl_quic_poll_translate_test_step_cb_arg);
477
0
#endif
478
479
0
        switch (item->desc.type) {
480
0
        case BIO_POLL_DESCRIPTOR_TYPE_SSL:
481
0
            ssl = item->desc.value.ssl;
482
0
            if (ssl == NULL)
483
                /* NULL items are no-ops and have revents reported as 0 */
484
0
                break;
485
486
0
            switch (ssl->type) {
487
0
#ifndef OPENSSL_NO_QUIC
488
0
            case SSL_TYPE_QUIC_LISTENER:
489
0
            case SSL_TYPE_QUIC_CONNECTION:
490
0
            case SSL_TYPE_QUIC_XSO:
491
0
                if (!poll_translate_ssl_quic(ssl, wctx, rpb, item->events,
492
0
                        abort_blocking))
493
0
                    FAIL_ITEM(i);
494
495
0
                if (*abort_blocking)
496
0
                    goto out;
497
498
0
                if (!SSL_get_event_timeout(ssl, &timeout, &is_infinite))
499
0
                    FAIL_ITEM(i++); /* need to clean up this item too */
500
501
0
                if (!is_infinite)
502
0
                    earliest_wakeup_deadline
503
0
                        = ossl_time_min(earliest_wakeup_deadline,
504
0
                            ossl_time_add(ossl_time_now(),
505
0
                                ossl_time_from_timeval(timeout)));
506
507
0
                break;
508
0
#endif
509
510
0
#ifndef OPENSSL_NO_DTLS
511
0
            case SSL_TYPE_DTLS_LISTENER:
512
0
                if (!poll_translate_ssl_dtls_listener(ssl, rpb, item->events,
513
0
                        abort_blocking))
514
0
                    FAIL_ITEM(i);
515
516
0
                if (*abort_blocking)
517
0
                    goto out;
518
519
0
                break;
520
0
            case SSL_TYPE_SSL_CONNECTION:
521
0
                if (SSL_is_dtls(ssl)) {
522
0
                    if (!poll_translate_ssl_dtls_conn(ssl, rpb, item->events,
523
0
                            abort_blocking))
524
0
                        FAIL_ITEM(i);
525
526
0
                    if (*abort_blocking)
527
0
                        goto out;
528
529
                    /*
530
                     * Bound the wait by the DTLS retransmission timer,
531
                     * otherwise a poll with no timeout sleeps straight through
532
                     * the point at which we should be retransmitting.
533
                     *
534
                     * Unless the caller has told us not to. A waiter which
535
                     * cannot service the timer must not be woken by it: it
536
                     * would find the timeout still expired on the next wait,
537
                     * which reads as a zero deadline, and spin.
538
                     */
539
0
                    if (bound_by_event_timeout) {
540
0
                        if (!SSL_get_event_timeout(ssl, &timeout, &is_infinite))
541
0
                            FAIL_ITEM(i++); /* need to clean up this item too */
542
543
0
                        if (!is_infinite)
544
0
                            earliest_wakeup_deadline
545
0
                                = ossl_time_min(earliest_wakeup_deadline,
546
0
                                    ossl_time_add(ossl_time_now(),
547
0
                                        ossl_time_from_timeval(timeout)));
548
0
                    }
549
550
0
                } else {
551
0
                    ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
552
0
                        "SSL_poll currently only supports DTLS listeners for DTLS connections");
553
0
                }
554
0
                break;
555
0
#endif
556
557
0
            default:
558
0
                ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
559
0
                    "SSL_poll currently only supports QUIC SSL "
560
0
                    "objects");
561
0
                FAIL_ITEM(i);
562
0
            }
563
0
            break;
564
565
0
        case BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD:
566
0
            ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
567
0
                "SSL_poll currently does not support polling "
568
0
                "sockets");
569
0
            FAIL_ITEM(i);
570
571
0
        default:
572
0
            ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
573
0
                "SSL_poll does not support unknown poll descriptor "
574
0
                "type %d",
575
0
                item->desc.type);
576
0
            FAIL_ITEM(i);
577
0
        }
578
0
    }
579
580
0
out:
581
    /*
582
     * On abort_blocking, the item which triggered the abort has already
583
     * balanced its own enter/leave of the blocking section (see
584
     * poll_translate_ssl_quic()); only items 0..i-1 still need cleanup here.
585
     */
586
0
    if (!ok || *abort_blocking)
587
0
        postpoll_translation_cleanup(items, i, stride, wctx);
588
589
0
    *p_earliest_wakeup_deadline = earliest_wakeup_deadline;
590
0
    *p_result_count = result_count;
591
0
    return ok;
592
0
}
593
594
static int poll_block(SSL_POLL_ITEM *items,
595
    size_t num_items,
596
    size_t stride,
597
    OSSL_TIME user_deadline,
598
    int bound_by_event_timeout,
599
    size_t *p_result_count)
600
0
{
601
0
    int ok = 0, abort_blocking = 0;
602
0
    RIO_POLL_BUILDER rpb;
603
0
    QUIC_REACTOR_WAIT_CTX wctx;
604
0
    OSSL_TIME earliest_wakeup_deadline;
605
606
    /*
607
     * Blocking is somewhat involved and involves the following steps:
608
     *
609
     * - Translation, in which the various logical items (SSL objects, etc.) to
610
     *   be polled are translated into items an OS polling API understands.
611
     *
612
     * - Synchronisation bookkeeping. This ensures that we can be woken up
613
     *   not just by readiness of any underlying file descriptor distilled from
614
     *   the provided items but also by other threads, which might do work
615
     *   on a relevant QUIC object to cause the object to be ready without the
616
     *   underlying file descriptor ever becoming ready from our perspective.
617
     *
618
     * - The blocking call to the OS polling API.
619
     *
620
     * - Currently we do not do reverse translation but simply call
621
     *   poll_readout() again to read out all readiness state for all
622
     *   descriptors which the user passed.
623
     *
624
     *   TODO(QUIC POLLING): In the future we will do reverse translation here
625
     *   also to facilitate a more efficient readout.
626
     */
627
0
#ifndef OPENSSL_NO_QUIC
628
0
    ossl_quic_reactor_wait_ctx_init(&wctx);
629
0
#endif
630
0
    ossl_rio_poll_builder_init(&rpb);
631
632
0
    if (!poll_translate(items, num_items, stride, &wctx, &rpb,
633
0
            &earliest_wakeup_deadline,
634
0
            &abort_blocking,
635
0
            bound_by_event_timeout,
636
0
            p_result_count))
637
0
        goto out;
638
639
0
    if (abort_blocking) {
640
        /*
641
         * Nothing actually failed; we just shouldn't block because an item
642
         * may have become ready while we were setting up. The caller's
643
         * retry loop will call poll_readout() again to pick this up.
644
         */
645
0
        ok = 1;
646
0
        goto out;
647
0
    }
648
649
0
    earliest_wakeup_deadline = ossl_time_min(earliest_wakeup_deadline,
650
0
        user_deadline);
651
652
0
    ok = ossl_rio_poll_builder_poll(&rpb, earliest_wakeup_deadline);
653
654
0
    postpoll_translation_cleanup(items, num_items, stride, &wctx);
655
656
0
out:
657
0
    ossl_rio_poll_builder_cleanup(&rpb);
658
0
#ifndef OPENSSL_NO_QUIC
659
0
    ossl_quic_reactor_wait_ctx_cleanup(&wctx);
660
0
#endif
661
0
    return ok;
662
0
}
663
664
#ifndef OPENSSL_NO_DTLS
665
/*
666
 * Wait until the given DTLS listener or listener-based connection may have
667
 * become ready for one of the given events, or until the deadline expires.
668
 *
669
 * This is the wait that libssl itself performs when a DTLS object is used in
670
 * blocking mode. It is the same wait SSL_poll() performs, and reuses it, so a
671
 * blocking call is woken by the same means an application polling the object
672
 * would be: readiness of the listener's socket, or the listener's notifier if
673
 * another thread produces readiness without the socket becoming readable here.
674
 *
675
 * No readout is performed. A spurious wakeup is always possible - the socket
676
 * becoming readable says nothing about which connection the datagram is for -
677
 * so the caller must re-test its own condition and wait again if needed.
678
 *
679
 * bound_by_event_timeout says whether the connection's own event timeout, which
680
 * for DTLS is the retransmission timer, should shorten the wait. Pass 1 unless
681
 * the caller is unable to service that timer when it fires: waking for a
682
 * timeout nothing then handles leaves it expired, and an expired timeout reads
683
 * as a zero deadline, so every later wait returns at once.
684
 *
685
 * Returns 1 if the wait completed and 0 on error.
686
 */
687
int ossl_dtls_block_until_ready(SSL *ssl, uint64_t events, OSSL_TIME deadline,
688
    int bound_by_event_timeout)
689
0
{
690
0
    SSL_POLL_ITEM item;
691
0
    size_t result_count = 0;
692
693
0
    item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL;
694
0
    item.desc.value.ssl = ssl;
695
0
    item.events = events;
696
0
    item.revents = 0;
697
698
0
    return poll_block(&item, 1, sizeof(item), deadline, bound_by_event_timeout,
699
0
        &result_count);
700
0
}
701
#endif /* OPENSSL_NO_DTLS */
702
#endif
703
704
static int poll_readout(SSL_POLL_ITEM *items,
705
    size_t num_items,
706
    size_t stride,
707
    int do_tick,
708
    size_t *p_result_count)
709
0
{
710
0
    int ok = 1;
711
0
    size_t i, result_count = 0;
712
0
    SSL_POLL_ITEM *item;
713
0
    SSL *ssl;
714
0
#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS)
715
0
    uint64_t events;
716
0
#endif
717
0
    uint64_t revents;
718
719
0
    for (i = 0; i < num_items; ++i) {
720
0
        item = &ITEM_N(items, stride, i);
721
0
#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS)
722
0
        events = item->events;
723
0
#endif
724
0
        revents = 0;
725
726
0
        switch (item->desc.type) {
727
0
        case BIO_POLL_DESCRIPTOR_TYPE_SSL:
728
0
            ssl = item->desc.value.ssl;
729
0
            if (ssl == NULL)
730
                /* NULL items are no-ops and have revents reported as 0 */
731
0
                break;
732
733
0
            switch (ssl->type) {
734
0
#ifndef OPENSSL_NO_QUIC
735
0
            case SSL_TYPE_QUIC_LISTENER:
736
0
            case SSL_TYPE_QUIC_CONNECTION:
737
0
            case SSL_TYPE_QUIC_XSO:
738
0
                if (!ossl_quic_conn_poll_events(ssl, events, do_tick, &revents))
739
                    /* above call raises ERR */
740
0
                    FAIL_ITEM(i);
741
742
0
                if (revents != 0)
743
0
                    ++result_count;
744
745
0
                break;
746
0
#endif
747
748
0
#ifndef OPENSSL_NO_DTLS
749
0
            case SSL_TYPE_DTLS_LISTENER:
750
0
                if (!ossl_dtls_listener_poll_events(ssl, events, do_tick, &revents))
751
                    /* above call raises ERR */
752
0
                    FAIL_ITEM(i);
753
754
0
                if (revents != 0)
755
0
                    ++result_count;
756
0
                break;
757
0
            case SSL_TYPE_SSL_CONNECTION:
758
0
                if (SSL_is_dtls(ssl)) {
759
0
                    if (!ossl_dtls_conn_poll_events(ssl, events, do_tick, &revents))
760
                        /* above call raises ERR */
761
0
                        FAIL_ITEM(i);
762
763
0
                    if (revents != 0)
764
0
                        ++result_count;
765
0
                } else {
766
                    /* TLS Connections not supported */
767
0
                    ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
768
0
                        "SSL_poll currently only supports QUIC and DTLS SSL objects");
769
0
                    FAIL_ITEM(i);
770
0
                }
771
0
                break;
772
0
#endif
773
774
0
            default:
775
0
                ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
776
0
                    "SSL_poll currently only supports QUIC and DTLS SSL objects");
777
0
                FAIL_ITEM(i);
778
0
            }
779
0
            break;
780
0
        case BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD:
781
0
            ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
782
0
                "SSL_poll currently does not support polling "
783
0
                "sockets");
784
0
            FAIL_ITEM(i);
785
0
        default:
786
0
            ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
787
0
                "SSL_poll does not support unknown poll descriptor "
788
0
                "type %d",
789
0
                item->desc.type);
790
0
            FAIL_ITEM(i);
791
0
        }
792
793
0
        item->revents = revents;
794
0
    }
795
796
0
out:
797
0
    if (p_result_count != NULL)
798
0
        *p_result_count = result_count;
799
800
0
    return ok;
801
0
}
802
803
int SSL_poll(SSL_POLL_ITEM *items,
804
    size_t num_items,
805
    size_t stride,
806
    const struct timeval *timeout,
807
    uint64_t flags,
808
    size_t *p_result_count)
809
0
{
810
0
    int ok = 1;
811
0
    size_t result_count = 0;
812
0
    ossl_unused int do_tick = ((flags & SSL_POLL_FLAG_NO_HANDLE_EVENTS) == 0);
813
0
    OSSL_TIME deadline;
814
815
    /* Trivial case. */
816
0
    if (num_items == 0) {
817
0
        if (timeout == NULL)
818
0
            goto out;
819
0
        OSSL_sleep(ossl_time2ms(ossl_time_from_timeval(*timeout)));
820
0
        goto out;
821
0
    }
822
823
    /* Convert timeout to deadline. */
824
0
    if (timeout == NULL)
825
0
        deadline = ossl_time_infinite();
826
0
    else if (timeout->tv_sec == 0 && timeout->tv_usec == 0)
827
0
        deadline = ossl_time_zero();
828
0
    else
829
0
        deadline = ossl_time_add(ossl_time_now(),
830
0
            ossl_time_from_timeval(*timeout));
831
832
    /* Loop until we have something to report. */
833
0
    for (;;) {
834
        /* Readout phase - poll current state of each item. */
835
0
        if (!poll_readout(items, num_items, stride, do_tick, &result_count)) {
836
0
            ok = 0;
837
0
            goto out;
838
0
        }
839
840
        /*
841
         * If we got anything, or we are in immediate mode (zero timeout), or
842
         * the deadline has expired, we're done.
843
         */
844
0
        if (result_count > 0
845
0
            || ossl_time_is_zero(deadline) /* (avoids now call) */
846
0
            || ossl_time_compare(ossl_time_now(), deadline) >= 0)
847
0
            goto out;
848
849
        /*
850
         * Block until something is ready. Ignore NO_HANDLE_EVENTS from this
851
         * point onwards.
852
         */
853
0
        do_tick = 1;
854
0
#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS)
855
0
        if (!poll_block(items, num_items, stride, deadline,
856
0
                /*bound_by_event_timeout=*/1, &result_count)) {
857
0
            ok = 0;
858
0
            goto out;
859
0
        }
860
0
#endif
861
0
    }
862
863
    /* TODO(QUIC POLLING): Support for polling FDs */
864
865
0
out:
866
0
    if (p_result_count != NULL)
867
0
        *p_result_count = result_count;
868
869
0
    return ok;
870
0
}