OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This test suite uses SSLClientSocket to test the implementation of | 5 // This test suite uses SSLClientSocket to test the implementation of |
6 // SSLServerSocket. In order to establish connections between the sockets | 6 // SSLServerSocket. In order to establish connections between the sockets |
7 // we need two additional classes: | 7 // we need two additional classes: |
8 // 1. FakeSocket | 8 // 1. FakeSocket |
9 // Connects SSL socket to FakeDataChannel. This class is just a stub. | 9 // Connects SSL socket to FakeDataChannel. This class is just a stub. |
10 // | 10 // |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "testing/platform_test.h" | 47 #include "testing/platform_test.h" |
48 | 48 |
49 namespace net { | 49 namespace net { |
50 | 50 |
51 namespace { | 51 namespace { |
52 | 52 |
53 class FakeDataChannel { | 53 class FakeDataChannel { |
54 public: | 54 public: |
55 FakeDataChannel() | 55 FakeDataChannel() |
56 : read_buf_len_(0), | 56 : read_buf_len_(0), |
57 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 57 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 58 closed_(false), |
| 59 write_called_after_close_(false) { |
58 } | 60 } |
59 | 61 |
60 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | 62 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback) { |
| 63 if (closed_) |
| 64 return 0; |
61 if (data_.empty()) { | 65 if (data_.empty()) { |
62 read_callback_ = callback; | 66 read_callback_ = callback; |
63 read_buf_ = buf; | 67 read_buf_ = buf; |
64 read_buf_len_ = buf_len; | 68 read_buf_len_ = buf_len; |
65 return net::ERR_IO_PENDING; | 69 return net::ERR_IO_PENDING; |
66 } | 70 } |
67 return PropogateData(buf, buf_len); | 71 return PropogateData(buf, buf_len); |
68 } | 72 } |
69 | 73 |
70 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | 74 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) { |
| 75 if (closed_) { |
| 76 if (write_called_after_close_) |
| 77 return net::ERR_CONNECTION_RESET; |
| 78 write_called_after_close_ = true; |
| 79 write_callback_ = callback; |
| 80 MessageLoop::current()->PostTask( |
| 81 FROM_HERE, base::Bind(&FakeDataChannel::DoWriteCallback, |
| 82 weak_factory_.GetWeakPtr())); |
| 83 return net::ERR_IO_PENDING; |
| 84 } |
71 data_.push(new net::DrainableIOBuffer(buf, buf_len)); | 85 data_.push(new net::DrainableIOBuffer(buf, buf_len)); |
72 MessageLoop::current()->PostTask( | 86 MessageLoop::current()->PostTask( |
73 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback, | 87 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback, |
74 weak_factory_.GetWeakPtr())); | 88 weak_factory_.GetWeakPtr())); |
75 return buf_len; | 89 return buf_len; |
76 } | 90 } |
77 | 91 |
| 92 // Closes the FakeDataChannel. After Close() is called, Read() returns 0, |
| 93 // indicating EOF, and Write() fails with ERR_CONNECTION_RESET. Note that |
| 94 // after the FakeDataChannel is closed, the first Write() call completes |
| 95 // asynchronously, which is necessary to reproduce bug 127822. |
| 96 void Close() { |
| 97 closed_ = true; |
| 98 } |
| 99 |
78 private: | 100 private: |
79 void DoReadCallback() { | 101 void DoReadCallback() { |
80 if (read_callback_.is_null() || data_.empty()) | 102 if (read_callback_.is_null() || data_.empty()) |
81 return; | 103 return; |
82 | 104 |
83 int copied = PropogateData(read_buf_, read_buf_len_); | 105 int copied = PropogateData(read_buf_, read_buf_len_); |
84 CompletionCallback callback = read_callback_; | 106 CompletionCallback callback = read_callback_; |
85 read_callback_.Reset(); | 107 read_callback_.Reset(); |
86 read_buf_ = NULL; | 108 read_buf_ = NULL; |
87 read_buf_len_ = 0; | 109 read_buf_len_ = 0; |
88 callback.Run(copied); | 110 callback.Run(copied); |
89 } | 111 } |
90 | 112 |
| 113 void DoWriteCallback() { |
| 114 if (write_callback_.is_null()) |
| 115 return; |
| 116 |
| 117 CompletionCallback callback = write_callback_; |
| 118 write_callback_.Reset(); |
| 119 callback.Run(net::ERR_CONNECTION_RESET); |
| 120 } |
| 121 |
91 int PropogateData(scoped_refptr<net::IOBuffer> read_buf, int read_buf_len) { | 122 int PropogateData(scoped_refptr<net::IOBuffer> read_buf, int read_buf_len) { |
92 scoped_refptr<net::DrainableIOBuffer> buf = data_.front(); | 123 scoped_refptr<net::DrainableIOBuffer> buf = data_.front(); |
93 int copied = std::min(buf->BytesRemaining(), read_buf_len); | 124 int copied = std::min(buf->BytesRemaining(), read_buf_len); |
94 memcpy(read_buf->data(), buf->data(), copied); | 125 memcpy(read_buf->data(), buf->data(), copied); |
95 buf->DidConsume(copied); | 126 buf->DidConsume(copied); |
96 | 127 |
97 if (!buf->BytesRemaining()) | 128 if (!buf->BytesRemaining()) |
98 data_.pop(); | 129 data_.pop(); |
99 return copied; | 130 return copied; |
100 } | 131 } |
101 | 132 |
102 CompletionCallback read_callback_; | 133 CompletionCallback read_callback_; |
103 scoped_refptr<net::IOBuffer> read_buf_; | 134 scoped_refptr<net::IOBuffer> read_buf_; |
104 int read_buf_len_; | 135 int read_buf_len_; |
105 | 136 |
| 137 CompletionCallback write_callback_; |
| 138 |
106 std::queue<scoped_refptr<net::DrainableIOBuffer> > data_; | 139 std::queue<scoped_refptr<net::DrainableIOBuffer> > data_; |
107 | 140 |
108 base::WeakPtrFactory<FakeDataChannel> weak_factory_; | 141 base::WeakPtrFactory<FakeDataChannel> weak_factory_; |
109 | 142 |
| 143 // True if Close() has been called. |
| 144 bool closed_; |
| 145 |
| 146 // Controls the completion of Write() after the FakeDataChannel is closed. |
| 147 // After the FakeDataChannel is closed, the first Write() call completes |
| 148 // asynchronously. |
| 149 bool write_called_after_close_; |
| 150 |
110 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel); | 151 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel); |
111 }; | 152 }; |
112 | 153 |
113 class FakeSocket : public StreamSocket { | 154 class FakeSocket : public StreamSocket { |
114 public: | 155 public: |
115 FakeSocket(FakeDataChannel* incoming_channel, | 156 FakeSocket(FakeDataChannel* incoming_channel, |
116 FakeDataChannel* outgoing_channel) | 157 FakeDataChannel* outgoing_channel) |
117 : incoming_(incoming_channel), | 158 : incoming_(incoming_channel), |
118 outgoing_(outgoing_channel) { | 159 outgoing_(outgoing_channel) { |
119 } | 160 } |
(...skipping 20 matching lines...) Expand all Loading... |
140 } | 181 } |
141 | 182 |
142 virtual bool SetSendBufferSize(int32 size) OVERRIDE { | 183 virtual bool SetSendBufferSize(int32 size) OVERRIDE { |
143 return true; | 184 return true; |
144 } | 185 } |
145 | 186 |
146 virtual int Connect(const CompletionCallback& callback) OVERRIDE { | 187 virtual int Connect(const CompletionCallback& callback) OVERRIDE { |
147 return net::OK; | 188 return net::OK; |
148 } | 189 } |
149 | 190 |
150 virtual void Disconnect() OVERRIDE {} | 191 virtual void Disconnect() OVERRIDE { |
| 192 incoming_->Close(); |
| 193 outgoing_->Close(); |
| 194 } |
151 | 195 |
152 virtual bool IsConnected() const OVERRIDE { | 196 virtual bool IsConnected() const OVERRIDE { |
153 return true; | 197 return true; |
154 } | 198 } |
155 | 199 |
156 virtual bool IsConnectedAndIdle() const OVERRIDE { | 200 virtual bool IsConnectedAndIdle() const OVERRIDE { |
157 return true; | 201 return true; |
158 } | 202 } |
159 | 203 |
160 virtual int GetPeerAddress(AddressList* address) const OVERRIDE { | 204 virtual int GetPeerAddress(AddressList* address) const OVERRIDE { |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 EXPECT_TRUE(server_ret > 0 || server_ret == net::ERR_IO_PENDING); | 466 EXPECT_TRUE(server_ret > 0 || server_ret == net::ERR_IO_PENDING); |
423 server_ret = read_callback.GetResult(server_ret); | 467 server_ret = read_callback.GetResult(server_ret); |
424 ASSERT_GT(server_ret, 0); | 468 ASSERT_GT(server_ret, 0); |
425 read_buf->DidConsume(server_ret); | 469 read_buf->DidConsume(server_ret); |
426 } | 470 } |
427 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed()); | 471 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed()); |
428 read_buf->SetOffset(0); | 472 read_buf->SetOffset(0); |
429 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size())); | 473 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size())); |
430 } | 474 } |
431 | 475 |
| 476 // A regression test for bug 127822 (http://crbug.com/127822). |
| 477 // If the server closes the connection after the handshake is finished, |
| 478 // the client's Write() call should not cause an infinite loop. |
| 479 // NOTE: this is a test for SSLClientSocket rather than SSLServerSocket. |
| 480 TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) { |
| 481 Initialize(); |
| 482 |
| 483 TestCompletionCallback connect_callback; |
| 484 TestCompletionCallback handshake_callback; |
| 485 |
| 486 // Establish connection. |
| 487 int client_ret = client_socket_->Connect(connect_callback.callback()); |
| 488 ASSERT_TRUE(client_ret == net::OK || client_ret == net::ERR_IO_PENDING); |
| 489 |
| 490 int server_ret = server_socket_->Handshake(handshake_callback.callback()); |
| 491 ASSERT_TRUE(server_ret == net::OK || server_ret == net::ERR_IO_PENDING); |
| 492 |
| 493 client_ret = connect_callback.GetResult(client_ret); |
| 494 ASSERT_EQ(net::OK, client_ret); |
| 495 server_ret = handshake_callback.GetResult(server_ret); |
| 496 ASSERT_EQ(net::OK, server_ret); |
| 497 |
| 498 scoped_refptr<net::StringIOBuffer> write_buf = |
| 499 new net::StringIOBuffer("testing123"); |
| 500 |
| 501 // The server closes the connection. The server needs to write some |
| 502 // data first so that the client's Read() calls from the transport |
| 503 // socket won't return ERR_IO_PENDING. This ensures that the client |
| 504 // will call Read() on the transport socket again. |
| 505 TestCompletionCallback write_callback; |
| 506 |
| 507 server_ret = server_socket_->Write(write_buf, write_buf->size(), |
| 508 write_callback.callback()); |
| 509 EXPECT_TRUE(server_ret > 0 || server_ret == net::ERR_IO_PENDING); |
| 510 |
| 511 server_ret = write_callback.GetResult(server_ret); |
| 512 EXPECT_GT(server_ret, 0); |
| 513 |
| 514 server_socket_->Disconnect(); |
| 515 |
| 516 // The client writes some data. This should not cause an infinite loop. |
| 517 client_ret = client_socket_->Write(write_buf, write_buf->size(), |
| 518 write_callback.callback()); |
| 519 EXPECT_TRUE(client_ret > 0 || client_ret == net::ERR_IO_PENDING); |
| 520 |
| 521 client_ret = write_callback.GetResult(client_ret); |
| 522 EXPECT_GT(client_ret, 0); |
| 523 |
| 524 MessageLoop::current()->PostDelayedTask( |
| 525 FROM_HERE, MessageLoop::QuitClosure(), |
| 526 base::TimeDelta::FromMilliseconds(10)); |
| 527 MessageLoop::current()->Run(); |
| 528 } |
| 529 |
432 // This test executes ExportKeyingMaterial() on the client and server sockets, | 530 // This test executes ExportKeyingMaterial() on the client and server sockets, |
433 // after connecting them, and verifies that the results match. | 531 // after connecting them, and verifies that the results match. |
434 // This test will fail if False Start is enabled (see crbug.com/90208). | 532 // This test will fail if False Start is enabled (see crbug.com/90208). |
435 TEST_F(SSLServerSocketTest, ExportKeyingMaterial) { | 533 TEST_F(SSLServerSocketTest, ExportKeyingMaterial) { |
436 Initialize(); | 534 Initialize(); |
437 | 535 |
438 TestCompletionCallback connect_callback; | 536 TestCompletionCallback connect_callback; |
439 TestCompletionCallback handshake_callback; | 537 TestCompletionCallback handshake_callback; |
440 | 538 |
441 int client_ret = client_socket_->Connect(connect_callback.callback()); | 539 int client_ret = client_socket_->Connect(connect_callback.callback()); |
(...skipping 29 matching lines...) Expand all Loading... |
471 unsigned char client_bad[kKeyingMaterialSize]; | 569 unsigned char client_bad[kKeyingMaterialSize]; |
472 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad, | 570 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad, |
473 false, kKeyingContext, | 571 false, kKeyingContext, |
474 client_bad, sizeof(client_bad)); | 572 client_bad, sizeof(client_bad)); |
475 ASSERT_EQ(rv, net::OK); | 573 ASSERT_EQ(rv, net::OK); |
476 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out))); | 574 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out))); |
477 } | 575 } |
478 #endif | 576 #endif |
479 | 577 |
480 } // namespace net | 578 } // namespace net |
OLD | NEW |