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