Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: net/socket/socket_bio_adapter_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698