| 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 |