diff options
author | Matt Caswell <matt@openssl.org> | 2016-10-27 14:46:57 +0200 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-10-28 10:13:49 +0200 |
commit | a34ac5b8b9c1a3281b4ee545c46177f485fb4949 (patch) | |
tree | 90b6f05b16714ebe22c550fea245ba6d2fb495c9 /test/asynciotest.c | |
parent | A zero return from BIO_read()/BIO_write() could be retryable (diff) | |
download | openssl-a34ac5b8b9c1a3281b4ee545c46177f485fb4949.tar.xz openssl-a34ac5b8b9c1a3281b4ee545c46177f485fb4949.zip |
Add a test for BIO_read() returning 0 in SSL_read() (and also for write)
A BIO_read() 0 return indicates that a failure occurred that may be
retryable. An SSL_read() 0 return indicates a non-retryable failure. Check
that if BIO_read() returns 0, SSL_read() returns <0. Same for SSL_write().
The asyncio test filter BIO already returns 0 on a retryable failure so we
build on that.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'test/asynciotest.c')
-rw-r--r-- | test/asynciotest.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/test/asynciotest.c b/test/asynciotest.c index 720cc7c662..23d0907dc9 100644 --- a/test/asynciotest.c +++ b/test/asynciotest.c @@ -234,12 +234,17 @@ static int async_puts(BIO *bio, const char *str) return async_write(bio, str, strlen(str)); } +#define MAX_ATTEMPTS 100 + int main(int argc, char *argv[]) { SSL_CTX *serverctx = NULL, *clientctx = NULL; SSL *serverssl = NULL, *clientssl = NULL; BIO *s_to_c_fbio = NULL, *c_to_s_fbio = NULL; - int test, err = 1; + int test, err = 1, ret; + size_t i, j; + const char testdata[] = "Test data"; + char buf[sizeof(testdata)]; CRYPTO_set_mem_debug(1); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); @@ -287,6 +292,42 @@ int main(int argc, char *argv[]) goto end; } + /* + * Send and receive some test data. Do the whole thing twice to ensure + * we hit at least one async event in both reading and writing + */ + for (j = 0; j < 2; j++) { + /* + * Write some test data. It should never take more than 2 attempts + * (the first one might be a retryable fail). A zero return from + * SSL_write() is a non-retryable failure, so fail immediately if + * we get that. + */ + for (ret = -1, i = 0; ret < 0 && i < 2 * sizeof(testdata); i++) + ret = SSL_write(clientssl, testdata, sizeof(testdata)); + if (ret <= 0) { + printf("Test %d failed: Failed to write app data\n", test); + goto end; + } + /* + * Now read the test data. It may take more attemps here because + * it could fail once for each byte read, including all overhead + * bytes from the record header/padding etc. Fail immediately if we + * get a zero return from SSL_read(). + */ + for (ret = -1, i = 0; ret < 0 && i < MAX_ATTEMPTS; i++) + ret = SSL_read(serverssl, buf, sizeof(buf)); + if (ret <= 0) { + printf("Test %d failed: Failed to read app data\n", test); + goto end; + } + if (ret != sizeof(testdata) + || memcmp(buf, testdata, sizeof(testdata)) != 0) { + printf("Test %d failed: Unexpected app data received\n", test); + goto end; + } + } + /* Also frees the BIOs */ SSL_free(clientssl); SSL_free(serverssl); |