123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /*
- * 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 revents;
- ossl_unused uint64_t events;
- ossl_unused int do_tick = ((flags & SSL_POLL_FLAG_NO_HANDLE_EVENTS) == 0);
- int is_immediate
- = (timeout != NULL
- && timeout->tv_sec == 0 && timeout->tv_usec == 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);
- }
- /* 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) {
- #ifndef OPENSSL_NO_QUIC
- case SSL_TYPE_QUIC_CONNECTION:
- case SSL_TYPE_QUIC_XSO:
- if (!ossl_quic_conn_poll_events(ssl, events, do_tick, &revents))
- /* above call raises ERR */
- FAIL_ITEM(i);
- if (revents != 0)
- ++result_count;
- break;
- #endif
- 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 */
- out:
- if (p_result_count != NULL)
- *p_result_count = result_count;
- return ok;
- }
|