summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2024-02-02 12:19:15 +0000
committerHugo Landau <hlandau@openssl.org>2024-02-10 11:37:14 +0000
commitab05f13cedb6cb1f058381676ae28652f7e4534d (patch)
treec5f590115880e8869482dc9b75fac98f017d1b96 /ssl
parent125c7c11a31a1645ac4b8da9c9fc367b1d080294 (diff)
QUIC RIO: Add frontend SSL_poll implementation
Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/23495)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/build.info2
-rw-r--r--ssl/rio/build.info3
-rw-r--r--ssl/rio/poll_immediate.c131
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;
+}