1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*
* 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);
}
/* 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, do_tick, &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 */
out:
if (p_result_count != NULL)
*p_result_count = result_count;
return ok;
}
|