Home | History | Annotate | Line # | Download | only in radix
      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 
     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 
    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