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 #if defined(_AIX)
11 /*
12 * Some versions of AIX define macros for events and revents for use when
13 * accessing pollfd structures (see Github issue #24236). That interferes
14 * with our use of these names here. We simply undef them.
15 */
16 # undef revents
17 # undef events
18 #endif
19
20 /*
21 * Test Scripts
22 * ============================================================================
23 */
24
25 /*
26 * Test: simple_conn
27 * -----------------
28 */
29 DEF_SCRIPT(simple_conn, "simple connection to server")
30 {
31 size_t i;
32
33 for (i = 0; i < 2; ++i) {
34 if (i == 0) {
35 OP_SIMPLE_PAIR_CONN_D();
36 } else {
37 OP_CLEAR();
38 OP_SIMPLE_PAIR_CONN();
39 }
40
41 OP_WRITE_B(C, "apple");
42
43 OP_ACCEPT_CONN_WAIT(L, La, 0);
44 OP_ACCEPT_CONN_NONE(L);
45
46 OP_READ_EXPECT_B(La, "apple");
47 OP_WRITE_B(La, "orange");
48 OP_READ_EXPECT_B(C, "orange");
49 }
50 }
51
52 DEF_SCRIPT(simple_thread_child,
53 "test that RADIX multithreading is working (child)")
54 {
55 }
56
57 /*
58 * Test: simple_thread
59 * -------------------
60 */
61 DEF_SCRIPT(simple_thread,
62 "test that RADIX multithreading is working")
63 {
64 size_t i;
65
66 for (i = 0; i < 2; ++i)
67 OP_SPAWN_THREAD(simple_thread_child);
68 }
69
70 /*
71 * Test: ssl_poll
72 * --------------
73 */
74 DEF_SCRIPT(ssl_poll_child,
75 "test that SSL_poll is working (child)")
76 {
77 OP_SLEEP(100);
78 OP_WRITE_B(C0, "extra");
79 }
80
DEF_FUNC(ssl_poll_check)81 DEF_FUNC(ssl_poll_check)
82 {
83 int ok = 0;
84 SSL *La, *Lax[4];
85 SSL_POLL_ITEM items[6] = {0}, expected_items[6] = {0};
86 size_t result_count = 0, i;
87 const struct timeval z_timeout = {0}, *p_timeout = &z_timeout;
88 struct timeval timeout = {0};
89 uint64_t mode;
90 size_t expected_result_count;
91 OSSL_TIME time_before, time_after;
92
93 F_POP(mode);
94 REQUIRE_SSL_5(La, Lax[0], Lax[1], Lax[2], Lax[3]);
95
96 items[0].desc = SSL_as_poll_descriptor(La);
97 items[0].events = 0;
98 items[0].revents = 0;
99
100 for (i = 0; i < 4; ++i) {
101 items[i + 1].desc = SSL_as_poll_descriptor(Lax[i]);
102 items[i + 1].events = SSL_POLL_EVENT_R | SSL_POLL_EVENT_I;
103 items[i + 1].revents = 0;
104 }
105
106 items[5].desc = SSL_as_poll_descriptor(SSL_get0_listener(La));
107
108 switch (mode) {
109 case 0: /* Nothing ready */
110 case 2:
111 expected_result_count = 0;
112 break;
113 case 1: /* Various events reported correctly */
114 expected_result_count = 5;
115 items[0].events = SSL_POLL_EVENT_OS;
116 expected_items[0].revents = SSL_POLL_EVENT_OS;
117
118 expected_items[1].revents = SSL_POLL_EVENT_R;
119
120 for (i = 0; i < 4; ++i) {
121 items[i + 1].events |= SSL_POLL_EVENT_W;
122 expected_items[i + 1].revents |= SSL_POLL_EVENT_W;
123 }
124
125 break;
126 case 3: /* Blocking test */
127 expected_result_count = 1;
128 expected_items[1].revents = SSL_POLL_EVENT_R;
129
130 p_timeout = &timeout;
131 timeout.tv_sec = 10;
132 timeout.tv_usec = 0;
133 break;
134 case 4: /* Listener test */
135 expected_result_count = 1;
136 items[5].events = SSL_POLL_EVENT_IC;
137 expected_items[5].revents = SSL_POLL_EVENT_IC;
138 break;
139 default:
140 goto err;
141 }
142
143 /* Zero-timeout call. */
144 result_count = SIZE_MAX;
145 time_before = ossl_time_now();
146 if (!TEST_true(SSL_poll(items, OSSL_NELEM(items), sizeof(SSL_POLL_ITEM),
147 p_timeout, 0, &result_count)))
148 goto err;
149
150 time_after = ossl_time_now();
151 if (!TEST_size_t_eq(result_count, expected_result_count))
152 goto err;
153
154 for (i = 0; i < OSSL_NELEM(items); ++i)
155 if (!TEST_uint64_t_eq(items[i].revents, expected_items[i].revents))
156 goto err;
157
158 /*
159 * The SSL_poll call for the blocking test definitely shouldn't have
160 * returned sooner than in 100ms.
161 */
162 if (i == 3 && !TEST_uint64_t_ge(ossl_time2ms(ossl_time_subtract(time_after, time_before)), 100))
163 goto err;
164
165 ok = 1;
166 err:
167 return ok;
168 }
169
170 DEF_SCRIPT(ssl_poll,
171 "test that SSL_poll is working")
172 {
173 size_t i;
174
175 OP_SIMPLE_PAIR_CONN_ND();
176
177 /* Setup streams */
178 OP_NEW_STREAM(C, C0, 0);
179 OP_WRITE_B(C0, "apple");
180
181 OP_NEW_STREAM(C, C1, 0);
182 OP_WRITE_B(C1, "orange");
183
184 OP_NEW_STREAM(C, C2, 0);
185 OP_WRITE_B(C2, "Strawberry");
186
187 OP_NEW_STREAM(C, C3, 0);
188 OP_WRITE_B(C3, "sync");
189
190 OP_ACCEPT_CONN_WAIT1_ND(L, La, 0);
191
192 OP_ACCEPT_STREAM_WAIT(La, La0, 0);
193 OP_READ_EXPECT_B(La0, "apple");
194
195 OP_ACCEPT_STREAM_WAIT(La, La1, 0);
196 OP_READ_EXPECT_B(La1, "orange");
197
198 OP_ACCEPT_STREAM_WAIT(La, La2, 0);
199 OP_READ_EXPECT_B(La2, "Strawberry");
200
201 OP_ACCEPT_STREAM_WAIT(La, La3, 0);
202 OP_READ_EXPECT_B(La3, "sync");
203
204 for (i = 0; i <= 4; ++i) {
205 /* 0: Check nothing ready */
206 /* 1: Check that various events are reported correctly */
207 /* 2: Check nothing ready */
208 /* 3: Blocking call unblocked from child thread */
209 /* 4: Listener test */
210
211 if (i == 1) {
212 OP_WRITE_B(C0, "orange");
213 OP_WRITE_B(C3, "sync");
214 OP_READ_EXPECT_B(La3, "sync");
215 } else if (i == 2) {
216 OP_READ_EXPECT_B(La0, "orange");
217 } else if (i == 3) {
218 OP_SPAWN_THREAD(ssl_poll_child);
219 } else if (i == 4) {
220 OP_NEW_SSL_C(Cb);
221 OP_SET_PEER_ADDR_FROM(Cb, L);
222 OP_CONNECT_WAIT(Cb);
223 }
224
225 OP_SELECT_SSL(0, La);
226 OP_SELECT_SSL(1, La0);
227 OP_SELECT_SSL(2, La1);
228 OP_SELECT_SSL(3, La2);
229 OP_SELECT_SSL(4, La3);
230 OP_PUSH_U64(i);
231 OP_FUNC(ssl_poll_check);
232
233 if (i == 3)
234 OP_READ_EXPECT_B(La0, "extra");
235
236 if (i == 4) {
237 OP_ACCEPT_CONN_WAIT1_ND(L, Lb, 0);
238 OP_NEW_STREAM(Lb, Lb0, 0);
239 OP_WRITE_B(Lb0, "foo");
240 OP_READ_EXPECT_B(Cb, "foo");
241 }
242 }
243 }
244
DEF_FUNC(check_writeable)245 DEF_FUNC(check_writeable)
246 {
247 int ok = 0;
248 SSL *ssl;
249 SSL_POLL_ITEM item;
250 size_t result_count = 0;
251 uint64_t expect;
252 const struct timeval z_timeout = {0}, *p_timeout = &z_timeout;
253
254 F_POP(expect);
255 REQUIRE_SSL(ssl);
256
257 item.desc = SSL_as_poll_descriptor(ssl);
258 item.events = SSL_POLL_EVENT_W;
259 item.revents = 0;
260
261 /* Zero-timeout call. */
262 result_count = SIZE_MAX;
263 if (!TEST_true(SSL_poll(&item, 1, sizeof(SSL_POLL_ITEM),
264 p_timeout, 0, &result_count)))
265 goto err;
266
267 ok = (!!(item.revents & SSL_POLL_EVENT_W) == expect);
268
269 err:
270 return ok;
271 }
272
273 DEF_SCRIPT(check_cwm, "check stream obeys cwm")
274 {
275 OP_SIMPLE_PAIR_CONN();
276
277 /* Create the initial stream by writing some data */
278 OP_WRITE_RAND(C, 1024);
279
280 /* We should be writeable at the start */
281 OP_PUSH_U64(1);
282 OP_SELECT_SSL(0, C);
283 OP_FUNC(check_writeable);
284
285 /* Default stream cwm is 512k (we already sent 1k). Consume all the rest */
286 OP_WRITE_RAND(C, 511 * 1024);
287
288 /* Confirm we are no longer writeable */
289 OP_PUSH_U64(0);
290 OP_SELECT_SSL(0, C);
291 OP_FUNC(check_writeable);
292
293 /* We now expect writes to fail */
294 OP_WRITE_FAIL(C);
295 }
296
297 /*
298 * List of Test Scripts
299 * ============================================================================
300 */
301 static SCRIPT_INFO *const scripts[] = {
302 USE(simple_conn)
303 USE(simple_thread)
304 USE(ssl_poll)
305 USE(check_cwm)
306 };
307