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

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

Issue 7399025: Fix instability in SSL client/server sockets (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 9 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « net/socket/ssl_server_socket_nss.cc ('k') | remoting/protocol/jingle_session_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 //
11 // 2. FakeDataChannel 11 // 2. FakeDataChannel
12 // Implements the actual exchange of data between two FakeSockets. 12 // Implements the actual exchange of data between two FakeSockets.
13 // 13 //
14 // Implementations of these two classes are included in this file. 14 // Implementations of these two classes are included in this file.
15 15
16 #include "net/socket/ssl_server_socket.h" 16 #include "net/socket/ssl_server_socket.h"
17 17
18 #include <stdlib.h>
19
18 #include <queue> 20 #include <queue>
19 21
22 #include "base/compiler_specific.h"
20 #include "base/file_path.h" 23 #include "base/file_path.h"
21 #include "base/file_util.h" 24 #include "base/file_util.h"
25 #include "base/message_loop.h"
22 #include "base/path_service.h" 26 #include "base/path_service.h"
23 #include "crypto/nss_util.h" 27 #include "crypto/nss_util.h"
24 #include "crypto/rsa_private_key.h" 28 #include "crypto/rsa_private_key.h"
25 #include "net/base/address_list.h" 29 #include "net/base/address_list.h"
26 #include "net/base/cert_status_flags.h" 30 #include "net/base/cert_status_flags.h"
27 #include "net/base/cert_verifier.h" 31 #include "net/base/cert_verifier.h"
28 #include "net/base/host_port_pair.h" 32 #include "net/base/host_port_pair.h"
29 #include "net/base/io_buffer.h" 33 #include "net/base/io_buffer.h"
30 #include "net/base/ip_endpoint.h" 34 #include "net/base/ip_endpoint.h"
31 #include "net/base/net_errors.h" 35 #include "net/base/net_errors.h"
32 #include "net/base/net_log.h" 36 #include "net/base/net_log.h"
33 #include "net/base/ssl_config_service.h" 37 #include "net/base/ssl_config_service.h"
34 #include "net/base/ssl_info.h" 38 #include "net/base/ssl_info.h"
35 #include "net/base/x509_certificate.h" 39 #include "net/base/x509_certificate.h"
36 #include "net/socket/client_socket_factory.h" 40 #include "net/socket/client_socket_factory.h"
37 #include "net/socket/socket_test_util.h" 41 #include "net/socket/socket_test_util.h"
38 #include "net/socket/ssl_client_socket.h" 42 #include "net/socket/ssl_client_socket.h"
39 #include "net/socket/stream_socket.h" 43 #include "net/socket/stream_socket.h"
40 #include "testing/gtest/include/gtest/gtest.h" 44 #include "testing/gtest/include/gtest/gtest.h"
41 #include "testing/platform_test.h" 45 #include "testing/platform_test.h"
42 46
43 namespace net { 47 namespace net {
44 48
45 namespace { 49 namespace {
46 50
47 class FakeDataChannel { 51 class FakeDataChannel {
48 public: 52 public:
49 FakeDataChannel() : read_callback_(NULL), read_buf_len_(0) { 53 FakeDataChannel()
54 : read_callback_(NULL),
55 read_buf_len_(0),
56 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
50 } 57 }
51 58
52 virtual int Read(IOBuffer* buf, int buf_len, 59 virtual int Read(IOBuffer* buf, int buf_len,
53 CompletionCallback* callback) { 60 CompletionCallback* callback) {
54 if (data_.empty()) { 61 if (data_.empty()) {
55 read_callback_ = callback; 62 read_callback_ = callback;
56 read_buf_ = buf; 63 read_buf_ = buf;
57 read_buf_len_ = buf_len; 64 read_buf_len_ = buf_len;
58 return net::ERR_IO_PENDING; 65 return net::ERR_IO_PENDING;
59 } 66 }
60 return PropogateData(buf, buf_len); 67 return PropogateData(buf, buf_len);
61 } 68 }
62 69
63 virtual int Write(IOBuffer* buf, int buf_len, 70 virtual int Write(IOBuffer* buf, int buf_len,
64 CompletionCallback* callback) { 71 CompletionCallback* callback) {
65 data_.push(new net::DrainableIOBuffer(buf, buf_len)); 72 data_.push(new net::DrainableIOBuffer(buf, buf_len));
66 DoReadCallback(); 73 MessageLoop::current()->PostTask(
74 FROM_HERE, task_factory_.NewRunnableMethod(
75 &FakeDataChannel::DoReadCallback));
67 return buf_len; 76 return buf_len;
68 } 77 }
69 78
70 private: 79 private:
71 void DoReadCallback() { 80 void DoReadCallback() {
72 if (!read_callback_) 81 if (!read_callback_ || data_.empty())
73 return; 82 return;
74 83
75 int copied = PropogateData(read_buf_, read_buf_len_); 84 int copied = PropogateData(read_buf_, read_buf_len_);
76 net::CompletionCallback* callback = read_callback_; 85 net::CompletionCallback* callback = read_callback_;
77 read_callback_ = NULL; 86 read_callback_ = NULL;
78 read_buf_ = NULL; 87 read_buf_ = NULL;
79 read_buf_len_ = 0; 88 read_buf_len_ = 0;
80 callback->Run(copied); 89 callback->Run(copied);
81 } 90 }
82 91
83 int PropogateData(scoped_refptr<net::IOBuffer> read_buf, int read_buf_len) { 92 int PropogateData(scoped_refptr<net::IOBuffer> read_buf, int read_buf_len) {
84 scoped_refptr<net::DrainableIOBuffer> buf = data_.front(); 93 scoped_refptr<net::DrainableIOBuffer> buf = data_.front();
85 int copied = std::min(buf->BytesRemaining(), read_buf_len); 94 int copied = std::min(buf->BytesRemaining(), read_buf_len);
86 memcpy(read_buf->data(), buf->data(), copied); 95 memcpy(read_buf->data(), buf->data(), copied);
87 buf->DidConsume(copied); 96 buf->DidConsume(copied);
88 97
89 if (!buf->BytesRemaining()) 98 if (!buf->BytesRemaining())
90 data_.pop(); 99 data_.pop();
91 return copied; 100 return copied;
92 } 101 }
93 102
94 net::CompletionCallback* read_callback_; 103 net::CompletionCallback* read_callback_;
95 scoped_refptr<net::IOBuffer> read_buf_; 104 scoped_refptr<net::IOBuffer> read_buf_;
96 int read_buf_len_; 105 int read_buf_len_;
97 106
98 std::queue<scoped_refptr<net::DrainableIOBuffer> > data_; 107 std::queue<scoped_refptr<net::DrainableIOBuffer> > data_;
99 108
109 ScopedRunnableMethodFactory<FakeDataChannel> task_factory_;
110
100 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel); 111 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel);
101 }; 112 };
102 113
103 class FakeSocket : public StreamSocket { 114 class FakeSocket : public StreamSocket {
104 public: 115 public:
105 FakeSocket(FakeDataChannel* incoming_channel, 116 FakeSocket(FakeDataChannel* incoming_channel,
106 FakeDataChannel* outgoing_channel) 117 FakeDataChannel* outgoing_channel)
107 : incoming_(incoming_channel), 118 : incoming_(incoming_channel),
108 outgoing_(outgoing_channel) { 119 outgoing_(outgoing_channel) {
109 } 120 }
110 121
111 virtual ~FakeSocket() { 122 virtual ~FakeSocket() {
112
113 } 123 }
114 124
115 virtual int Read(IOBuffer* buf, int buf_len, 125 virtual int Read(IOBuffer* buf, int buf_len,
116 CompletionCallback* callback) { 126 CompletionCallback* callback) {
127 // Read random number of bytes.
128 buf_len = rand() % buf_len + 1;
117 return incoming_->Read(buf, buf_len, callback); 129 return incoming_->Read(buf, buf_len, callback);
118 } 130 }
119 131
120 virtual int Write(IOBuffer* buf, int buf_len, 132 virtual int Write(IOBuffer* buf, int buf_len,
121 CompletionCallback* callback) { 133 CompletionCallback* callback) {
134 // Write random number of bytes.
135 buf_len = rand() % buf_len + 1;
122 return outgoing_->Write(buf, buf_len, callback); 136 return outgoing_->Write(buf, buf_len, callback);
123 } 137 }
124 138
125 virtual bool SetReceiveBufferSize(int32 size) { 139 virtual bool SetReceiveBufferSize(int32 size) {
126 return true; 140 return true;
127 } 141 }
128 142
129 virtual bool SetSendBufferSize(int32 size) { 143 virtual bool SetSendBufferSize(int32 size) {
130 return true; 144 return true;
131 } 145 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 FakeSocket client(&channel_1, &channel_2); 211 FakeSocket client(&channel_1, &channel_2);
198 FakeSocket server(&channel_2, &channel_1); 212 FakeSocket server(&channel_2, &channel_1);
199 213
200 const char kTestData[] = "testing123"; 214 const char kTestData[] = "testing123";
201 const int kTestDataSize = strlen(kTestData); 215 const int kTestDataSize = strlen(kTestData);
202 const int kReadBufSize = 1024; 216 const int kReadBufSize = 1024;
203 scoped_refptr<net::IOBuffer> write_buf = new net::StringIOBuffer(kTestData); 217 scoped_refptr<net::IOBuffer> write_buf = new net::StringIOBuffer(kTestData);
204 scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(kReadBufSize); 218 scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(kReadBufSize);
205 219
206 // Write then read. 220 // Write then read.
207 EXPECT_EQ(kTestDataSize, server.Write(write_buf, kTestDataSize, NULL)); 221 int written = server.Write(write_buf, kTestDataSize, NULL);
208 EXPECT_EQ(kTestDataSize, client.Read(read_buf, kReadBufSize, NULL)); 222 EXPECT_GT(written, 0);
209 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), kTestDataSize)); 223 EXPECT_LE(written, kTestDataSize);
224
225 int read = client.Read(read_buf, kReadBufSize, NULL);
226 EXPECT_GT(read, 0);
227 EXPECT_LE(read, written);
228 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
210 229
211 // Read then write. 230 // Read then write.
212 TestCompletionCallback callback; 231 TestCompletionCallback callback;
213 EXPECT_EQ(net::ERR_IO_PENDING, 232 EXPECT_EQ(net::ERR_IO_PENDING,
214 server.Read(read_buf, kReadBufSize, &callback)); 233 server.Read(read_buf, kReadBufSize, &callback));
215 EXPECT_EQ(kTestDataSize, client.Write(write_buf, kTestDataSize, NULL)); 234
216 EXPECT_EQ(kTestDataSize, callback.WaitForResult()); 235 written = client.Write(write_buf, kTestDataSize, NULL);
217 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), kTestDataSize)); 236 EXPECT_GT(written, 0);
237 EXPECT_LE(written, kTestDataSize);
238
239 read = callback.WaitForResult();
240 EXPECT_GT(read, 0);
241 EXPECT_LE(read, written);
242 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
218 } 243 }
219 244
220 class SSLServerSocketTest : public PlatformTest { 245 class SSLServerSocketTest : public PlatformTest {
221 public: 246 public:
222 SSLServerSocketTest() 247 SSLServerSocketTest()
223 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) { 248 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) {
224 } 249 }
225 250
226 protected: 251 protected:
227 void Initialize() { 252 void Initialize() {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 EXPECT_GT(read_callback.WaitForResult(), 0); 401 EXPECT_GT(read_callback.WaitForResult(), 0);
377 } 402 }
378 if (client_ret == net::ERR_IO_PENDING) { 403 if (client_ret == net::ERR_IO_PENDING) {
379 EXPECT_GT(write_callback.WaitForResult(), 0); 404 EXPECT_GT(write_callback.WaitForResult(), 0);
380 } 405 }
381 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size())); 406 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
382 } 407 }
383 #endif 408 #endif
384 409
385 } // namespace net 410 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_server_socket_nss.cc ('k') | remoting/protocol/jingle_session_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698