@@ -10458,6 +10458,57 @@ TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
1045810458 write_failed = false ;
1045910459}
1046010460
10461+ // Test that intermittent inability to read results in retryable error
10462+ TEST (SSLTest, IntermittentEmptyRead) {
10463+ bssl::UniquePtr<SSL_CTX> client_ctx (SSL_CTX_new (TLS_method ()));
10464+ bssl::UniquePtr<SSL_CTX> server_ctx =
10465+ CreateContextWithTestCertificate (TLS_method ());
10466+ ASSERT_TRUE (client_ctx);
10467+ ASSERT_TRUE (server_ctx);
10468+ bssl::UniquePtr<SSL> client, server;
10469+ ASSERT_TRUE (ConnectClientAndServer (&client, &server, client_ctx.get (),
10470+ server_ctx.get ()));
10471+
10472+ // Create a fake read BIO that returns 0 on read to simulate empty read
10473+ bssl::UniquePtr<BIO_METHOD> method (BIO_meth_new (0 , nullptr ));
10474+ ASSERT_TRUE (method);
10475+ BIO_meth_set_create (method.get (), [](BIO *b) -> int {
10476+ BIO_set_init (b, 1 );
10477+ return 1 ;
10478+ });
10479+ BIO_meth_set_read (method.get (), [](BIO *, char *, int ) -> int {
10480+ return 0 ;
10481+ });
10482+ bssl::UniquePtr<BIO> rbio_empty (BIO_new (method.get ()));
10483+ ASSERT_TRUE (rbio_empty);
10484+ BIO_set_flags (rbio_empty.get (), BIO_FLAGS_READ);
10485+
10486+ // Save off client rbio and use empty read BIO
10487+ bssl::UniquePtr<BIO> client_rbio (SSL_get_rbio (client.get ()));
10488+ ASSERT_TRUE (client_rbio);
10489+ // Up-ref |client_rbio| as SSL_CTX dtor will also attempt to free it
10490+ ASSERT_TRUE (BIO_up_ref (client_rbio.get ()));
10491+ SSL_set0_rbio (client.get (), rbio_empty.release ());
10492+
10493+ // Server writes some data to the client
10494+ const uint8_t data[1 ] = {0 };
10495+ int ret = SSL_write (server.get (), data, (int ) sizeof (data));
10496+ EXPECT_EQ (ret, (int ) sizeof (data));
10497+ EXPECT_EQ (SSL_get_error (server.get (), ret), SSL_ERROR_NONE);
10498+
10499+ // On empty read, client should still want a read so caller will retry
10500+ uint8_t buf[1 ];
10501+ ret = SSL_read (client.get (), buf, sizeof (buf));
10502+ EXPECT_EQ (ret, 0 );
10503+ EXPECT_EQ (SSL_get_error (client.get (), ret), SSL_ERROR_WANT_READ);
10504+
10505+ // Reset client rbio, read should succeed
10506+ SSL_set0_rbio (client.get (), client_rbio.release ());
10507+ ret = SSL_read (client.get (), buf, sizeof (buf));
10508+ EXPECT_EQ (ret, (int ) sizeof (buf));
10509+ EXPECT_EQ (SSL_get_error (client.get (), ret), SSL_ERROR_NONE);
10510+ }
10511+
1046110512// Test that |SSL_shutdown|, when quiet shutdown is enabled, simulates receiving
1046210513// a close_notify, down to |SSL_read| reporting |SSL_ERROR_ZERO_RETURN|.
1046310514TEST (SSLTest, QuietShutdown) {
0 commit comments