diff options
-rw-r--r-- | ssl/build.info | 2 | ||||
-rw-r--r-- | ssl/rio/build.info | 3 | ||||
-rw-r--r-- | ssl/rio/poll_immediate.c | 131 |
3 files changed, 135 insertions, 1 deletions
diff --git a/ssl/build.info b/ssl/build.info index 00e9e8fd7d..de28a0700a 100644 --- a/ssl/build.info +++ b/ssl/build.info @@ -1,4 +1,4 @@ -SUBDIRS=record +SUBDIRS=record rio LIBS=../libssl diff --git a/ssl/rio/build.info b/ssl/rio/build.info new file mode 100644 index 0000000000..c8dc4a3cb9 --- /dev/null +++ b/ssl/rio/build.info @@ -0,0 +1,3 @@ +$LIBSSL=../../libssl + +SOURCE[$LIBSSL]=poll_immediate.c diff --git a/ssl/rio/poll_immediate.c b/ssl/rio/poll_immediate.c new file mode 100644 index 0000000000..7de211742a --- /dev/null +++ b/ssl/rio/poll_immediate.c @@ -0,0 +1,131 @@ +/* + * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/common.h" +#include <openssl/ssl.h> +#include <openssl/err.h> +#include "../ssl_local.h" + +#define ITEM_N(items, stride, n) \ + (*(SSL_POLL_ITEM *)((char *)(items) + (n)*(stride))) + +#define FAIL_FROM(n) \ + do { \ + size_t j; \ + \ + for (j = (n); j < num_items; ++j) \ + ITEM_N(items, stride, j).revents = 0; \ + \ + ok = 0; \ + goto out; \ + } while (0) + +#define FAIL_ITEM(i) \ + do { \ + ITEM_N(items, stride, i).revents = SSL_POLL_EVENT_F; \ + ++result_count; \ + FAIL_FROM(i + 1); \ + } while (0) + +int SSL_poll(SSL_POLL_ITEM *items, + size_t num_items, + size_t stride, + const struct timeval *timeout, + uint64_t flags, + size_t *p_result_count) +{ + int ok = 1; + size_t i, result_count = 0; + SSL_POLL_ITEM *item; + SSL *ssl; + uint64_t events, revents; + int is_immediate + = (timeout != NULL + && timeout->tv_sec == 0 && timeout->tv_usec == 0); + int do_tick = ((flags & SSL_POLL_FLAG_NO_HANDLE_EVENTS) == 0); + + /* + * Prevent calls which use SSL_poll functionality which is not currently + * supported. + */ + if (!is_immediate) { + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll does not currently support blocking " + "operation"); + FAIL_FROM(0); + } + + if (do_tick) { + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll does not currently support implicit I/O " + "processing"); + FAIL_FROM(0); + } + + /* Trivial case. */ + if (num_items == 0) + goto out; + + /* Poll current state of each item. */ + for (i = 0; i < num_items; ++i) { + item = &ITEM_N(items, stride, i); + events = item->events; + revents = 0; + + switch (item->desc.type) { + case BIO_POLL_DESCRIPTOR_TYPE_SSL: + ssl = item->desc.value.ssl; + if (ssl == NULL) + /* NULL items are no-ops and have revents reported as 0 */ + break; + + switch (ssl->type) { + case SSL_TYPE_QUIC_CONNECTION: + case SSL_TYPE_QUIC_XSO: + if (!ossl_quic_conn_poll_events(ssl, events, &revents)) + /* above call raises ERR */ + FAIL_ITEM(i); + + if (revents != 0) + ++result_count; + + break; + + default: + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll currently only supports QUIC SSL " + "objects"); + FAIL_ITEM(i); + } + break; + case BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD: + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll currently does not support polling " + "sockets"); + FAIL_ITEM(i); + default: + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll does not support unknown poll descriptor " + "type %d", item->desc.type); + FAIL_ITEM(i); + } + + item->revents = revents; + } + + /* TODO(QUIC POLLING): Blocking mode */ + /* TODO(QUIC POLLING): Support for polling FDs */ + /* TODO(QUIC POLLING): Support for autotick */ + +out: + if (p_result_count != NULL) + *p_result_count = result_count; + + return ok; +} |