Commit a34ac5b8 authored by Matt Caswell's avatar Matt Caswell
Browse files

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: default avatarRichard Levitte <levitte@openssl.org>
parent 4880672a
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -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);