From: Matt Caswell Date: Wed, 9 Apr 2025 12:08:09 +0000 (+0100) Subject: Test that SSL_poll does not report a stream as writable if it isn't X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=85a8eba56769c4d25a66e0b52e8fb3e76bbe4afe;p=thirdparty%2Fopenssl.git Test that SSL_poll does not report a stream as writable if it isn't We consume all the credit and check the stream is no longer writeable Reviewed-by: Neil Horman Reviewed-by: Saša Nedvědický Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/27319) --- diff --git a/test/radix/quic_ops.c b/test/radix/quic_ops.c index e3167a565ba..d987cfeadec 100644 --- a/test/radix/quic_ops.c +++ b/test/radix/quic_ops.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ #include "internal/sockets.h" +#include static const unsigned char alpn_ossltest[] = { /* "\x08ossltest" (hex for EBCDIC resilience) */ @@ -565,6 +566,40 @@ err: return ok; } +DEF_FUNC(hf_write_rand) +{ + int ok = 0, r; + SSL *ssl; + void *buf = NULL; + size_t buf_len, bytes_written = 0; + + F_POP(buf_len); + REQUIRE_SSL(ssl); + + while (buf_len > 0) { + size_t thislen = buf_len > 1024 ? 1024 : buf_len; + + if (buf == NULL) + buf = OPENSSL_malloc(thislen); + if (!TEST_ptr(buf)) + goto err; + if (!TEST_int_eq(RAND_bytes(buf, thislen), 1)) + goto err; + r = SSL_write_ex(ssl, buf, thislen, &bytes_written); + if (!TEST_true(r) + || !check_consistent_want(ssl, r) + || !TEST_size_t_eq(bytes_written, thislen)) + goto err; + + buf_len -= thislen; + } + + ok = 1; +err: + OPENSSL_free(buf); + return ok; +} + DEF_FUNC(hf_write_ex2) { int ok = 0, r; @@ -1112,6 +1147,11 @@ err: OP_PUSH_BUFP(buf, buf_len), \ OP_FUNC(hf_write)) +#define OP_WRITE_RAND(name, buf_len) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_SIZE(buf_len), \ + OP_FUNC(hf_write_rand)) + #define OP_WRITE_B(name, buf) \ OP_WRITE(name, (buf), sizeof(buf)) diff --git a/test/radix/quic_tests.c b/test/radix/quic_tests.c index 2a29f1e80fe..4fd207f0bd9 100644 --- a/test/radix/quic_tests.c +++ b/test/radix/quic_tests.c @@ -232,6 +232,58 @@ DEF_SCRIPT(ssl_poll, } } +DEF_FUNC(check_writeable) +{ + int ok = 0; + SSL *ssl; + SSL_POLL_ITEM item; + size_t result_count = 0; + uint64_t expect; + const struct timeval z_timeout = {0}, *p_timeout = &z_timeout; + + F_POP(expect); + REQUIRE_SSL(ssl); + + item.desc = SSL_as_poll_descriptor(ssl); + item.events = SSL_POLL_EVENT_W; + item.revents = 0; + + /* Zero-timeout call. */ + result_count = SIZE_MAX; + if (!TEST_true(SSL_poll(&item, 1, sizeof(SSL_POLL_ITEM), + p_timeout, 0, &result_count))) + goto err; + + ok = (!!(item.revents & SSL_POLL_EVENT_W) == expect); + + err: + return ok; +} + +DEF_SCRIPT(check_cwm, "check stream obeys cwm") +{ + OP_SIMPLE_PAIR_CONN(); + + /* Create the initial stream by writing some data */ + OP_WRITE_RAND(C, 1024); + + /* We should be writeable at the start */ + OP_PUSH_U64(1); + OP_SELECT_SSL(0, C); + OP_FUNC(check_writeable); + + /* Default stream cwm is 512k (we already sent 1k). Consume all the rest */ + OP_WRITE_RAND(C, 511 * 1024); + + /* Confirm we are no longer writeable */ + OP_PUSH_U64(0); + OP_SELECT_SSL(0, C); + OP_FUNC(check_writeable); + + /* We now expect writes to fail */ + OP_WRITE_FAIL(C); +} + /* * List of Test Scripts * ============================================================================ @@ -240,4 +292,5 @@ static SCRIPT_INFO *const scripts[] = { USE(simple_conn) USE(simple_thread) USE(ssl_poll) + USE(check_cwm) };