xref: /aosp_15_r20/external/cronet/net/socket/socket_bio_adapter_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/socket/socket_bio_adapter.h"
6 
7 #include <string.h>
8 
9 #include <memory>
10 
11 #include "base/check_op.h"
12 #include "base/containers/span.h"
13 #include "base/location.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/run_loop.h"
16 #include "build/build_config.h"
17 #include "crypto/openssl_util.h"
18 #include "net/base/address_list.h"
19 #include "net/base/completion_once_callback.h"
20 #include "net/base/net_errors.h"
21 #include "net/log/net_log_source.h"
22 #include "net/socket/socket_test_util.h"
23 #include "net/socket/stream_socket.h"
24 #include "net/ssl/openssl_ssl_util.h"
25 #include "net/test/test_with_task_environment.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/boringssl/src/include/openssl/bio.h"
28 #include "third_party/boringssl/src/include/openssl/err.h"
29 #include "third_party/boringssl/src/include/openssl/ssl.h"
30 
31 namespace net {
32 
33 enum ReadIfReadySupport {
34   // ReadyIfReady() is implemented.
35   READ_IF_READY_SUPPORTED,
36   // ReadyIfReady() is unimplemented.
37   READ_IF_READY_NOT_SUPPORTED,
38 };
39 
40 class SocketBIOAdapterTest : public testing::TestWithParam<ReadIfReadySupport>,
41                              public SocketBIOAdapter::Delegate,
42                              public WithTaskEnvironment {
43  protected:
SetUp()44   void SetUp() override {
45     if (GetParam() == READ_IF_READY_SUPPORTED) {
46       factory_.set_enable_read_if_ready(true);
47     }
48   }
49 
MakeTestSocket(SocketDataProvider * data)50   std::unique_ptr<StreamSocket> MakeTestSocket(SocketDataProvider* data) {
51     data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
52     factory_.AddSocketDataProvider(data);
53     std::unique_ptr<StreamSocket> socket = factory_.CreateTransportClientSocket(
54         AddressList(), nullptr, nullptr, nullptr, NetLogSource());
55     CHECK_EQ(OK, socket->Connect(CompletionOnceCallback()));
56     return socket;
57   }
58 
set_reset_on_write_ready(std::unique_ptr<SocketBIOAdapter> * reset_on_write_ready)59   void set_reset_on_write_ready(
60       std::unique_ptr<SocketBIOAdapter>* reset_on_write_ready) {
61     reset_on_write_ready_ = reset_on_write_ready;
62   }
63 
ExpectReadError(BIO * bio,int error,const crypto::OpenSSLErrStackTracer & tracer)64   void ExpectReadError(BIO* bio,
65                        int error,
66                        const crypto::OpenSSLErrStackTracer& tracer) {
67     // BIO_read should fail.
68     char buf;
69     EXPECT_EQ(-1, BIO_read(bio, &buf, 1));
70     EXPECT_EQ(error, MapOpenSSLError(SSL_ERROR_SSL, tracer));
71     EXPECT_FALSE(BIO_should_read(bio));
72 
73     // Repeating the operation should replay the error.
74     EXPECT_EQ(-1, BIO_read(bio, &buf, 1));
75     EXPECT_EQ(error, MapOpenSSLError(SSL_ERROR_SSL, tracer));
76     EXPECT_FALSE(BIO_should_read(bio));
77   }
78 
ExpectBlockingRead(BIO * bio,void * buf,int len)79   void ExpectBlockingRead(BIO* bio, void* buf, int len) {
80     // BIO_read should return a retryable error.
81     EXPECT_EQ(-1, BIO_read(bio, buf, len));
82     EXPECT_TRUE(BIO_should_read(bio));
83     EXPECT_EQ(0u, ERR_peek_error());
84 
85     // Repeating the operation has the same result.
86     EXPECT_EQ(-1, BIO_read(bio, buf, len));
87     EXPECT_TRUE(BIO_should_read(bio));
88     EXPECT_EQ(0u, ERR_peek_error());
89   }
90 
ExpectWriteError(BIO * bio,int error,const crypto::OpenSSLErrStackTracer & tracer)91   void ExpectWriteError(BIO* bio,
92                         int error,
93                         const crypto::OpenSSLErrStackTracer& tracer) {
94     // BIO_write should fail.
95     char buf = '?';
96     EXPECT_EQ(-1, BIO_write(bio, &buf, 1));
97     EXPECT_EQ(error, MapOpenSSLError(SSL_ERROR_SSL, tracer));
98     EXPECT_FALSE(BIO_should_write(bio));
99 
100     // Repeating the operation should replay the error.
101     EXPECT_EQ(-1, BIO_write(bio, &buf, 1));
102     EXPECT_EQ(error, MapOpenSSLError(SSL_ERROR_SSL, tracer));
103     EXPECT_FALSE(BIO_should_write(bio));
104   }
105 
ExpectBlockingWrite(BIO * bio,const void * buf,int len)106   void ExpectBlockingWrite(BIO* bio, const void* buf, int len) {
107     // BIO_write should return a retryable error.
108     EXPECT_EQ(-1, BIO_write(bio, buf, len));
109     EXPECT_TRUE(BIO_should_write(bio));
110     EXPECT_EQ(0u, ERR_peek_error());
111 
112     // Repeating the operation has the same result.
113     EXPECT_EQ(-1, BIO_write(bio, buf, len));
114     EXPECT_TRUE(BIO_should_write(bio));
115     EXPECT_EQ(0u, ERR_peek_error());
116   }
117 
WaitForReadReady()118   void WaitForReadReady() {
119     expect_read_ready_ = true;
120     base::RunLoop().RunUntilIdle();
121     EXPECT_FALSE(expect_read_ready_);
122   }
123 
WaitForWriteReady(SequencedSocketData * to_resume)124   void WaitForWriteReady(SequencedSocketData* to_resume) {
125     expect_write_ready_ = true;
126     if (to_resume) {
127       to_resume->Resume();
128     }
129     base::RunLoop().RunUntilIdle();
130     EXPECT_FALSE(expect_write_ready_);
131   }
132 
WaitForBothReady()133   void WaitForBothReady() {
134     expect_read_ready_ = true;
135     expect_write_ready_ = true;
136     base::RunLoop().RunUntilIdle();
137     EXPECT_FALSE(expect_read_ready_);
138     EXPECT_FALSE(expect_write_ready_);
139   }
140 
141   // SocketBIOAdapter::Delegate implementation:
OnReadReady()142   void OnReadReady() override {
143     EXPECT_TRUE(expect_read_ready_);
144     expect_read_ready_ = false;
145   }
146 
OnWriteReady()147   void OnWriteReady() override {
148     EXPECT_TRUE(expect_write_ready_);
149     expect_write_ready_ = false;
150     if (reset_on_write_ready_)
151       reset_on_write_ready_->reset();
152   }
153 
154  private:
155   bool expect_read_ready_ = false;
156   bool expect_write_ready_ = false;
157   MockClientSocketFactory factory_;
158   raw_ptr<std::unique_ptr<SocketBIOAdapter>> reset_on_write_ready_ = nullptr;
159 };
160 
161 INSTANTIATE_TEST_SUITE_P(All,
162                          SocketBIOAdapterTest,
163                          testing::Values(READ_IF_READY_SUPPORTED,
164                                          READ_IF_READY_NOT_SUPPORTED));
165 
166 // Test that data can be read synchronously.
TEST_P(SocketBIOAdapterTest,ReadSync)167 TEST_P(SocketBIOAdapterTest, ReadSync) {
168   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
169 
170   MockRead reads[] = {
171       MockRead(SYNCHRONOUS, 0, "hello"), MockRead(SYNCHRONOUS, 1, "world"),
172       MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET, 2),
173   };
174 
175   SequencedSocketData data(reads, base::span<MockWrite>());
176   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
177   std::unique_ptr<SocketBIOAdapter> adapter =
178       std::make_unique<SocketBIOAdapter>(socket.get(), 100, 100, this);
179   BIO* bio = adapter->bio();
180   EXPECT_FALSE(adapter->HasPendingReadData());
181 
182   // Read the data synchronously. Although the buffer has room for both,
183   // BIO_read only reports one socket-level Read.
184   char buf[10];
185   EXPECT_EQ(5, BIO_read(bio, buf, sizeof(buf)));
186   EXPECT_EQ(0, memcmp("hello", buf, 5));
187   EXPECT_FALSE(adapter->HasPendingReadData());
188 
189   // Consume the next portion one byte at a time.
190   EXPECT_EQ(1, BIO_read(bio, buf, 1));
191   EXPECT_EQ('w', buf[0]);
192   EXPECT_TRUE(adapter->HasPendingReadData());
193 
194   EXPECT_EQ(1, BIO_read(bio, buf, 1));
195   EXPECT_EQ('o', buf[0]);
196   EXPECT_TRUE(adapter->HasPendingReadData());
197 
198   // The remainder may be consumed in a single BIO_read.
199   EXPECT_EQ(3, BIO_read(bio, buf, sizeof(buf)));
200   EXPECT_EQ(0, memcmp("rld", buf, 3));
201   EXPECT_FALSE(adapter->HasPendingReadData());
202 
203   // The error is available synchoronously.
204   ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
205 }
206 
207 // Test that data can be read asynchronously.
TEST_P(SocketBIOAdapterTest,ReadAsync)208 TEST_P(SocketBIOAdapterTest, ReadAsync) {
209   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
210 
211   MockRead reads[] = {
212       MockRead(ASYNC, 0, "hello"), MockRead(ASYNC, 1, "world"),
213       MockRead(ASYNC, ERR_CONNECTION_RESET, 2),
214   };
215 
216   SequencedSocketData data(reads, base::span<MockWrite>());
217   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
218   std::unique_ptr<SocketBIOAdapter> adapter =
219       std::make_unique<SocketBIOAdapter>(socket.get(), 100, 100, this);
220   BIO* bio = adapter->bio();
221   EXPECT_FALSE(adapter->HasPendingReadData());
222 
223   // Attempt to read data. It will fail but schedule a Read.
224   char buf[10];
225   ExpectBlockingRead(bio, buf, sizeof(buf));
226   EXPECT_FALSE(adapter->HasPendingReadData());
227 
228   // After waiting, the data is available if Read() is used.
229   WaitForReadReady();
230   if (GetParam() == READ_IF_READY_SUPPORTED) {
231     EXPECT_FALSE(adapter->HasPendingReadData());
232   } else {
233     EXPECT_TRUE(adapter->HasPendingReadData());
234   }
235 
236   // The first read is now available synchronously.
237   EXPECT_EQ(5, BIO_read(bio, buf, sizeof(buf)));
238   EXPECT_EQ(0, memcmp("hello", buf, 5));
239   EXPECT_FALSE(adapter->HasPendingReadData());
240 
241   // The adapter does not schedule another Read until BIO_read is next called.
242   base::RunLoop().RunUntilIdle();
243   EXPECT_FALSE(adapter->HasPendingReadData());
244 
245   // This time, under-request the data. The adapter should still read the full
246   // amount.
247   ExpectBlockingRead(bio, buf, 1);
248   EXPECT_FALSE(adapter->HasPendingReadData());
249 
250   // After waiting, the data is available if Read() is used.
251   WaitForReadReady();
252   if (GetParam() == READ_IF_READY_SUPPORTED) {
253     EXPECT_FALSE(adapter->HasPendingReadData());
254   } else {
255     EXPECT_TRUE(adapter->HasPendingReadData());
256   }
257 
258   // The next read is now available synchronously.
259   EXPECT_EQ(5, BIO_read(bio, buf, sizeof(buf)));
260   EXPECT_EQ(0, memcmp("world", buf, 5));
261   EXPECT_FALSE(adapter->HasPendingReadData());
262 
263   // The error is not yet available.
264   ExpectBlockingRead(bio, buf, sizeof(buf));
265   WaitForReadReady();
266 
267   // The error is now available synchoronously.
268   ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
269 }
270 
271 // Test that synchronous EOF is mapped to ERR_CONNECTION_CLOSED.
TEST_P(SocketBIOAdapterTest,ReadEOFSync)272 TEST_P(SocketBIOAdapterTest, ReadEOFSync) {
273   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
274 
275   MockRead reads[] = {
276       MockRead(SYNCHRONOUS, 0, 0),
277   };
278 
279   SequencedSocketData data(reads, base::span<MockWrite>());
280   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
281   std::unique_ptr<SocketBIOAdapter> adapter =
282       std::make_unique<SocketBIOAdapter>(socket.get(), 100, 100, this);
283 
284   ExpectReadError(adapter->bio(), ERR_CONNECTION_CLOSED, tracer);
285 }
286 
287 #if BUILDFLAG(IS_ANDROID)
288 // Test that asynchronous EOF is mapped to ERR_CONNECTION_CLOSED.
289 // TODO(crbug.com/1480024): Test is flaky on Android.
290 #define MAYBE_ReadEOFAsync DISABLED_ReadEOFAsync
291 #else
292 #define MAYBE_ReadEOFAsync ReadEOFAsync
293 #endif
TEST_P(SocketBIOAdapterTest,MAYBE_ReadEOFAsync)294 TEST_P(SocketBIOAdapterTest, MAYBE_ReadEOFAsync) {
295   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
296 
297   MockRead reads[] = {
298       MockRead(ASYNC, 0, 0),
299   };
300 
301   SequencedSocketData data(reads, base::span<MockWrite>());
302   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
303   std::unique_ptr<SocketBIOAdapter> adapter =
304       std::make_unique<SocketBIOAdapter>(socket.get(), 100, 100, this);
305 
306   char buf;
307   ExpectBlockingRead(adapter->bio(), &buf, 1);
308   WaitForReadReady();
309   ExpectReadError(adapter->bio(), ERR_CONNECTION_CLOSED, tracer);
310 }
311 
312 // Test that data can be written synchronously.
TEST_P(SocketBIOAdapterTest,WriteSync)313 TEST_P(SocketBIOAdapterTest, WriteSync) {
314   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
315 
316   MockWrite writes[] = {
317       MockWrite(SYNCHRONOUS, 0, "hello"),
318       MockWrite(SYNCHRONOUS, 1, "wor"),
319       MockWrite(SYNCHRONOUS, 2, "ld"),
320       MockWrite(SYNCHRONOUS, 3, "helloworld"),
321       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 4),
322   };
323 
324   SequencedSocketData data(base::span<MockRead>(), writes);
325   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
326   std::unique_ptr<SocketBIOAdapter> adapter =
327       std::make_unique<SocketBIOAdapter>(socket.get(), 10, 10, this);
328   BIO* bio = adapter->bio();
329 
330   // Test data entering and leaving the buffer synchronously. The second write
331   // takes multiple iterations (events 0 to 2).
332   EXPECT_EQ(5, BIO_write(bio, "hello", 5));
333   EXPECT_EQ(5, BIO_write(bio, "world", 5));
334 
335   // If writing larger than the buffer size, only part of the data is written
336   // (event 3).
337   EXPECT_EQ(10, BIO_write(bio, "helloworldhelloworld", 20));
338 
339   // Writing "aaaaa" fails (event 4), but there is a write buffer, so errors
340   // are delayed.
341   EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
342 
343   // However once the error is registered, subsequent writes fail.
344   ExpectWriteError(bio, ERR_CONNECTION_RESET, tracer);
345 }
346 
347 // Test that data can be written asynchronously.
TEST_P(SocketBIOAdapterTest,WriteAsync)348 TEST_P(SocketBIOAdapterTest, WriteAsync) {
349   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
350 
351   MockWrite writes[] = {
352       MockWrite(ASYNC, 0, "aaa"),
353       MockWrite(ASYNC, ERR_IO_PENDING, 1),  // pause
354       MockWrite(ASYNC, 2, "aabbbbb"),
355       MockWrite(ASYNC, 3, "ccc"),
356       MockWrite(ASYNC, 4, "ddd"),
357       MockWrite(ASYNC, ERR_IO_PENDING, 5),  // pause
358       MockWrite(ASYNC, 6, "dd"),
359       MockWrite(SYNCHRONOUS, 7, "e"),
360       MockWrite(SYNCHRONOUS, 8, "e"),
361       MockWrite(ASYNC, 9, "e"),
362       MockWrite(ASYNC, 10, "ee"),
363       MockWrite(ASYNC, ERR_IO_PENDING, 11),  // pause
364       MockWrite(ASYNC, 12, "eff"),
365       MockWrite(ASYNC, 13, "ggggggg"),
366       MockWrite(ASYNC, ERR_CONNECTION_RESET, 14),
367   };
368 
369   SequencedSocketData data(base::span<MockRead>(), writes);
370   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
371   std::unique_ptr<SocketBIOAdapter> adapter =
372       std::make_unique<SocketBIOAdapter>(socket.get(), 10, 10, this);
373   BIO* bio = adapter->bio();
374 
375   // Data which fits in the buffer is returned synchronously, even if not
376   // flushed synchronously.
377   EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
378   EXPECT_EQ(5, BIO_write(bio, "bbbbb", 5));
379 
380   // The buffer contains:
381   //
382   //   [aaaaabbbbb]
383   //    ^
384 
385   // The buffer is full now, so the next write will block.
386   ExpectBlockingWrite(bio, "zzzzz", 5);
387 
388   // Let the first socket write complete (event 0) and pause (event 1).
389   WaitForWriteReady(nullptr);
390   EXPECT_TRUE(data.IsPaused());
391 
392   // The buffer contains:
393   //
394   //   [...aabbbbb]
395   //       ^
396 
397   // The ring buffer now has 3 bytes of space with "aabbbbb" still to be
398   // written. Attempting to write 3 bytes means 3 succeed.
399   EXPECT_EQ(3, BIO_write(bio, "cccccccccc", 10));
400 
401   // The buffer contains:
402   //
403   //   [cccaabbbbb]
404   //       ^
405 
406   // Drain the buffer (events 2 and 3).
407   WaitForWriteReady(&data);
408 
409   // The buffer is now empty.
410 
411   // Now test something similar but arrange for a BIO_write (the 'e's below) to
412   // wrap around the buffer.  Write five bytes into the buffer, flush the first
413   // three (event 4), and pause (event 5). OnWriteReady is not signaled because
414   // the buffer was not full.
415   EXPECT_EQ(5, BIO_write(bio, "ddddd", 5));
416   base::RunLoop().RunUntilIdle();
417   EXPECT_TRUE(data.IsPaused());
418 
419   // The buffer contains:
420   //
421   //   [...dd.....]
422   //       ^
423 
424   // The adapter maintains a ring buffer, so 6 bytes fit.
425   EXPECT_EQ(6, BIO_write(bio, "eeeeee", 6));
426 
427   // The buffer contains:
428   //
429   //   [e..ddeeeee]
430   //       ^
431 
432   // The remaining space may be filled in.
433   EXPECT_EQ(2, BIO_write(bio, "ffffffffff", 10));
434 
435   // The buffer contains:
436   //
437   //   [effddeeeee]
438   //       ^
439 
440   // Drain to the end of the ring buffer, so it wraps around (events 6 to 10)
441   // and pause (event 11). Test that synchronous and asynchronous writes both
442   // drain. The start of the buffer has now wrapped around.
443   WaitForWriteReady(&data);
444   EXPECT_TRUE(data.IsPaused());
445 
446   // The buffer contains:
447   //
448   //   [eff.......]
449   //    ^
450 
451   // Test wrapping around works correctly and the buffer may be appended to.
452   EXPECT_EQ(7, BIO_write(bio, "gggggggggg", 10));
453 
454   // The buffer contains:
455   //
456   //   [effggggggg]
457   //    ^
458 
459   // The buffer is full now, so the next write will block.
460   ExpectBlockingWrite(bio, "zzzzz", 5);
461 
462   // Drain the buffer to confirm the ring buffer's contents are as expected
463   // (events 12 and 13).
464   WaitForWriteReady(&data);
465 
466   // Write again so the write error may be discovered.
467   EXPECT_EQ(5, BIO_write(bio, "hhhhh", 5));
468 
469   // Release the write error (event 14). At this point future BIO_write calls
470   // fail. The buffer was not full, so OnWriteReady is not signalled.
471   base::RunLoop().RunUntilIdle();
472   ExpectWriteError(bio, ERR_CONNECTION_RESET, tracer);
473 }
474 
475 // Test that a failed socket write is reported through BIO_read and prevents it
476 // from scheduling a socket read. See https://crbug.com/249848.
TEST_P(SocketBIOAdapterTest,WriteStopsRead)477 TEST_P(SocketBIOAdapterTest, WriteStopsRead) {
478   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
479 
480   MockWrite writes[] = {
481       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 0),
482   };
483 
484   SequencedSocketData data(base::span<MockRead>(), writes);
485   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
486   std::unique_ptr<SocketBIOAdapter> adapter =
487       std::make_unique<SocketBIOAdapter>(socket.get(), 100, 100, this);
488   BIO* bio = adapter->bio();
489 
490   // The write fails, but there is a write buffer, so errors are delayed.
491   EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
492 
493   // The write error is surfaced out of BIO_read. There are no MockReads, so
494   // this also tests that no socket reads are attempted.
495   ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
496 }
497 
498 // Test that a synchronous failed socket write interrupts a blocked
499 // BIO_read. See https://crbug.com/249848.
TEST_P(SocketBIOAdapterTest,SyncWriteInterruptsRead)500 TEST_P(SocketBIOAdapterTest, SyncWriteInterruptsRead) {
501   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
502 
503   MockRead reads[] = {
504       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
505   };
506 
507   MockWrite writes[] = {
508       MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 1),
509   };
510 
511   SequencedSocketData data(reads, writes);
512   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
513   std::unique_ptr<SocketBIOAdapter> adapter =
514       std::make_unique<SocketBIOAdapter>(socket.get(), 100, 100, this);
515   BIO* bio = adapter->bio();
516 
517   // Attempt to read from the transport. It will block indefinitely.
518   char buf;
519   ExpectBlockingRead(adapter->bio(), &buf, 1);
520 
521   // Schedule a socket write.
522   EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
523 
524   // The write error triggers OnReadReady.
525   WaitForReadReady();
526 
527   // The write error is surfaced out of BIO_read.
528   ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
529 }
530 
531 // Test that an asynchronous failed socket write interrupts a blocked
532 // BIO_read. See https://crbug.com/249848.
TEST_P(SocketBIOAdapterTest,AsyncWriteInterruptsRead)533 TEST_P(SocketBIOAdapterTest, AsyncWriteInterruptsRead) {
534   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
535 
536   MockRead reads[] = {
537       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
538   };
539 
540   MockWrite writes[] = {
541       MockWrite(ASYNC, ERR_CONNECTION_RESET, 1),
542   };
543 
544   SequencedSocketData data(reads, writes);
545   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
546   std::unique_ptr<SocketBIOAdapter> adapter =
547       std::make_unique<SocketBIOAdapter>(socket.get(), 100, 100, this);
548   BIO* bio = adapter->bio();
549 
550   // Attempt to read from the transport. It will block indefinitely.
551   char buf;
552   ExpectBlockingRead(adapter->bio(), &buf, 1);
553 
554   // Schedule a socket write.
555   EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
556 
557   // The write error is signaled asynchronously and interrupts BIO_read, so
558   // OnReadReady is signaled. The write buffer was not full, so OnWriteReady is
559   // not signaled.
560   WaitForReadReady();
561 
562   // The write error is surfaced out of BIO_read.
563   ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
564 }
565 
566 // Test that an asynchronous failed socket write interrupts a blocked BIO_read,
567 // signaling both if the buffer was full. See https://crbug.com/249848.
TEST_P(SocketBIOAdapterTest,AsyncWriteInterruptsBoth)568 TEST_P(SocketBIOAdapterTest, AsyncWriteInterruptsBoth) {
569   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
570 
571   MockRead reads[] = {
572       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
573   };
574 
575   MockWrite writes[] = {
576       MockWrite(ASYNC, ERR_CONNECTION_RESET, 1),
577   };
578 
579   SequencedSocketData data(reads, writes);
580   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
581   std::unique_ptr<SocketBIOAdapter> adapter =
582       std::make_unique<SocketBIOAdapter>(socket.get(), 5, 5, this);
583   BIO* bio = adapter->bio();
584 
585   // Attempt to read from the transport. It will block indefinitely.
586   char buf;
587   ExpectBlockingRead(adapter->bio(), &buf, 1);
588 
589   // Schedule a socket write.
590   EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
591 
592   // The write error is signaled asynchronously and interrupts BIO_read, so
593   // OnReadReady is signaled. The write buffer was full, so both OnWriteReady is
594   // also signaled.
595   WaitForBothReady();
596 
597   // The write error is surfaced out of BIO_read.
598   ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
599 }
600 
601 // Test that SocketBIOAdapter handles OnWriteReady deleting itself when both
602 // need to be signaled.
TEST_P(SocketBIOAdapterTest,DeleteOnWriteReady)603 TEST_P(SocketBIOAdapterTest, DeleteOnWriteReady) {
604   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
605 
606   MockRead reads[] = {
607       MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
608   };
609 
610   MockWrite writes[] = {
611       MockWrite(ASYNC, ERR_CONNECTION_RESET, 1),
612   };
613 
614   SequencedSocketData data(reads, writes);
615   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
616   std::unique_ptr<SocketBIOAdapter> adapter =
617       std::make_unique<SocketBIOAdapter>(socket.get(), 5, 5, this);
618   BIO* bio = adapter->bio();
619 
620   // Arrange for OnReadReady and OnWriteReady to both be signaled due to write
621   // error propagation (see the AsyncWriteInterruptsBoth test).
622   char buf;
623   ExpectBlockingRead(adapter->bio(), &buf, 1);
624   EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
625 
626   // Both OnWriteReady and OnReadReady would be signaled, but OnWriteReady
627   // deletes the adapter first.
628   set_reset_on_write_ready(&adapter);
629   WaitForWriteReady(nullptr);
630 
631   EXPECT_FALSE(adapter);
632 }
633 
634 // Test that using a BIO after the underlying adapter is destroyed fails
635 // gracefully.
TEST_P(SocketBIOAdapterTest,Detached)636 TEST_P(SocketBIOAdapterTest, Detached) {
637   crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
638 
639   SequencedSocketData data;
640   std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
641   std::unique_ptr<SocketBIOAdapter> adapter =
642       std::make_unique<SocketBIOAdapter>(socket.get(), 100, 100, this);
643 
644   // Retain an additional reference to the BIO.
645   bssl::UniquePtr<BIO> bio = bssl::UpRef(adapter->bio());
646 
647   // Release the adapter.
648   adapter.reset();
649 
650   ExpectReadError(bio.get(), ERR_UNEXPECTED, tracer);
651   ExpectWriteError(bio.get(), ERR_UNEXPECTED, tracer);
652 }
653 
654 }  // namespace net
655