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 #include "net/socket/ssl_client_socket.h" | 5 #include "net/socket/ssl_client_socket.h" |
6 | 6 |
7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "net/base/address_list.h" | 10 #include "net/base/address_list.h" |
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 | 1167 |
1168 if (rv == ERR_IO_PENDING) | 1168 if (rv == ERR_IO_PENDING) |
1169 rv = callback.WaitForResult(); | 1169 rv = callback.WaitForResult(); |
1170 | 1170 |
1171 EXPECT_GE(rv, 0); | 1171 EXPECT_GE(rv, 0); |
1172 if (rv <= 0) | 1172 if (rv <= 0) |
1173 break; | 1173 break; |
1174 } | 1174 } |
1175 } | 1175 } |
1176 | 1176 |
| 1177 // Tests that SSLClientSocket properly handle when the underlying transport |
| 1178 // synchronously returns an error code on read failure. The error code should be |
| 1179 // echoed back so SSLv3 fallback logic can condition on it. |
| 1180 TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) { |
| 1181 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
| 1182 SpawnedTestServer::kLocalhost, |
| 1183 base::FilePath()); |
| 1184 ASSERT_TRUE(test_server.Start()); |
| 1185 |
| 1186 AddressList addr; |
| 1187 ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| 1188 |
| 1189 TestCompletionCallback callback; |
| 1190 scoped_ptr<StreamSocket> real_transport( |
| 1191 new TCPClientSocket(addr, NULL, NetLog::Source())); |
| 1192 scoped_ptr<SynchronousErrorStreamSocket> transport( |
| 1193 new SynchronousErrorStreamSocket(real_transport.Pass())); |
| 1194 int rv = callback.GetResult(transport->Connect(callback.callback())); |
| 1195 EXPECT_EQ(OK, rv); |
| 1196 |
| 1197 // Disable TLS False Start to avoid handshake non-determinism. |
| 1198 SSLConfig ssl_config; |
| 1199 ssl_config.false_start_enabled = false; |
| 1200 |
| 1201 SynchronousErrorStreamSocket* raw_transport = transport.get(); |
| 1202 scoped_ptr<SSLClientSocket> sock( |
| 1203 CreateSSLClientSocket(transport.PassAs<StreamSocket>(), |
| 1204 test_server.host_port_pair(), |
| 1205 ssl_config)); |
| 1206 |
| 1207 raw_transport->SetNextWriteError(ERR_CONNECTION_RESET); |
| 1208 |
| 1209 rv = callback.GetResult(sock->Connect(callback.callback())); |
| 1210 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1211 EXPECT_FALSE(sock->IsConnected()); |
| 1212 } |
| 1213 |
1177 // Tests that the SSLClientSocket properly handles when the underlying transport | 1214 // Tests that the SSLClientSocket properly handles when the underlying transport |
1178 // synchronously returns an error code - such as if an intermediary terminates | 1215 // synchronously returns an error code - such as if an intermediary terminates |
1179 // the socket connection uncleanly. | 1216 // the socket connection uncleanly. |
1180 // This is a regression test for http://crbug.com/238536 | 1217 // This is a regression test for http://crbug.com/238536 |
1181 TEST_F(SSLClientSocketTest, Read_WithSynchronousError) { | 1218 TEST_F(SSLClientSocketTest, Read_WithSynchronousError) { |
1182 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1219 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
1183 SpawnedTestServer::kLocalhost, | 1220 SpawnedTestServer::kLocalhost, |
1184 base::FilePath()); | 1221 base::FilePath()); |
1185 ASSERT_TRUE(test_server.Start()); | 1222 ASSERT_TRUE(test_server.Start()); |
1186 | 1223 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 // Simulate an unclean/forcible shutdown. | 1259 // Simulate an unclean/forcible shutdown. |
1223 raw_transport->SetNextReadError(ERR_CONNECTION_RESET); | 1260 raw_transport->SetNextReadError(ERR_CONNECTION_RESET); |
1224 | 1261 |
1225 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | 1262 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
1226 | 1263 |
1227 // Note: This test will hang if this bug has regressed. Simply checking that | 1264 // Note: This test will hang if this bug has regressed. Simply checking that |
1228 // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate | 1265 // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate |
1229 // result when using a dedicated task runner for NSS. | 1266 // result when using a dedicated task runner for NSS. |
1230 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); | 1267 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); |
1231 | 1268 |
1232 #if !defined(USE_OPENSSL) | |
1233 // SSLClientSocketNSS records the error exactly | |
1234 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1269 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
1235 #else | |
1236 // SSLClientSocketOpenSSL treats any errors as a simple EOF. | |
1237 EXPECT_EQ(0, rv); | |
1238 #endif | |
1239 } | 1270 } |
1240 | 1271 |
1241 // Tests that the SSLClientSocket properly handles when the underlying transport | 1272 // Tests that the SSLClientSocket properly handles when the underlying transport |
1242 // asynchronously returns an error code while writing data - such as if an | 1273 // asynchronously returns an error code while writing data - such as if an |
1243 // intermediary terminates the socket connection uncleanly. | 1274 // intermediary terminates the socket connection uncleanly. |
1244 // This is a regression test for http://crbug.com/249848 | 1275 // This is a regression test for http://crbug.com/249848 |
1245 TEST_F(SSLClientSocketTest, Write_WithSynchronousError) { | 1276 TEST_F(SSLClientSocketTest, Write_WithSynchronousError) { |
1246 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1277 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
1247 SpawnedTestServer::kLocalhost, | 1278 SpawnedTestServer::kLocalhost, |
1248 base::FilePath()); | 1279 base::FilePath()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 | 1334 |
1304 // Now unblock the outgoing request, having it fail with the connection | 1335 // Now unblock the outgoing request, having it fail with the connection |
1305 // being reset. | 1336 // being reset. |
1306 raw_transport->UnblockWrite(); | 1337 raw_transport->UnblockWrite(); |
1307 | 1338 |
1308 // Note: This will cause an inifite loop if this bug has regressed. Simply | 1339 // Note: This will cause an inifite loop if this bug has regressed. Simply |
1309 // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING | 1340 // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING |
1310 // is a legitimate result when using a dedicated task runner for NSS. | 1341 // is a legitimate result when using a dedicated task runner for NSS. |
1311 rv = callback.GetResult(rv); | 1342 rv = callback.GetResult(rv); |
1312 | 1343 |
1313 #if !defined(USE_OPENSSL) | |
1314 // SSLClientSocketNSS records the error exactly | |
1315 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1344 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
1316 #else | |
1317 // SSLClientSocketOpenSSL treats any errors as a simple EOF. | |
1318 EXPECT_EQ(0, rv); | |
1319 #endif | |
1320 } | 1345 } |
1321 | 1346 |
1322 // Test the full duplex mode, with Read and Write pending at the same time. | 1347 // Test the full duplex mode, with Read and Write pending at the same time. |
1323 // This test also serves as a regression test for http://crbug.com/29815. | 1348 // This test also serves as a regression test for http://crbug.com/29815. |
1324 TEST_F(SSLClientSocketTest, Read_FullDuplex) { | 1349 TEST_F(SSLClientSocketTest, Read_FullDuplex) { |
1325 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1350 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
1326 SpawnedTestServer::kLocalhost, | 1351 SpawnedTestServer::kLocalhost, |
1327 base::FilePath()); | 1352 base::FilePath()); |
1328 ASSERT_TRUE(test_server.Start()); | 1353 ASSERT_TRUE(test_server.Start()); |
1329 | 1354 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 ASSERT_EQ(ERR_IO_PENDING, rv); | 1509 ASSERT_EQ(ERR_IO_PENDING, rv); |
1485 ASSERT_FALSE(callback.have_result()); | 1510 ASSERT_FALSE(callback.have_result()); |
1486 | 1511 |
1487 // Now unblock Write(), which will invoke OnSendComplete and (eventually) | 1512 // Now unblock Write(), which will invoke OnSendComplete and (eventually) |
1488 // call the Read() callback, deleting the socket and thus aborting calling | 1513 // call the Read() callback, deleting the socket and thus aborting calling |
1489 // the Write() callback. | 1514 // the Write() callback. |
1490 raw_transport->UnblockWrite(); | 1515 raw_transport->UnblockWrite(); |
1491 | 1516 |
1492 rv = read_callback.WaitForResult(); | 1517 rv = read_callback.WaitForResult(); |
1493 | 1518 |
1494 #if !defined(USE_OPENSSL) | |
1495 // NSS records the error exactly. | |
1496 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1519 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
1497 #else | |
1498 // OpenSSL treats any errors as a simple EOF. | |
1499 EXPECT_EQ(0, rv); | |
1500 #endif | |
1501 | 1520 |
1502 // The Write callback should not have been called. | 1521 // The Write callback should not have been called. |
1503 EXPECT_FALSE(callback.have_result()); | 1522 EXPECT_FALSE(callback.have_result()); |
1504 } | 1523 } |
1505 | 1524 |
1506 // Tests that the SSLClientSocket does not crash if data is received on the | 1525 // Tests that the SSLClientSocket does not crash if data is received on the |
1507 // transport socket after a failing write. This can occur if we have a Write | 1526 // transport socket after a failing write. This can occur if we have a Write |
1508 // error in a SPDY socket. | 1527 // error in a SPDY socket. |
1509 // Regression test for http://crbug.com/335557 | 1528 // Regression test for http://crbug.com/335557 |
1510 TEST_F(SSLClientSocketTest, Read_WithWriteError) { | 1529 TEST_F(SSLClientSocketTest, Read_WithWriteError) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1585 rv = callback.GetResult(sock->Write(long_request_buffer.get(), | 1604 rv = callback.GetResult(sock->Write(long_request_buffer.get(), |
1586 long_request_buffer->BytesRemaining(), | 1605 long_request_buffer->BytesRemaining(), |
1587 callback.callback())); | 1606 callback.callback())); |
1588 if (rv > 0) { | 1607 if (rv > 0) { |
1589 long_request_buffer->DidConsume(rv); | 1608 long_request_buffer->DidConsume(rv); |
1590 // Abort if the entire buffer is ever consumed. | 1609 // Abort if the entire buffer is ever consumed. |
1591 ASSERT_LT(0, long_request_buffer->BytesRemaining()); | 1610 ASSERT_LT(0, long_request_buffer->BytesRemaining()); |
1592 } | 1611 } |
1593 } while (rv > 0); | 1612 } while (rv > 0); |
1594 | 1613 |
1595 #if !defined(USE_OPENSSL) | |
1596 // NSS records the error exactly. | |
1597 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1614 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
1598 #else | |
1599 // OpenSSL treats the reset as a generic protocol error. | |
1600 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv); | |
1601 #endif | |
1602 | 1615 |
1603 // Release the read. Some bytes should go through. | 1616 // Release the read. |
1604 raw_transport->UnblockReadResult(); | 1617 raw_transport->UnblockReadResult(); |
1605 rv = read_callback.WaitForResult(); | 1618 rv = read_callback.WaitForResult(); |
1606 | 1619 |
1607 // Per the fix for http://crbug.com/249848, write failures currently break | 1620 #if defined(USE_OPENSSL) |
1608 // reads. Change this assertion if they're changed to not collide. | 1621 // Should still read bytes despite the write error. |
| 1622 EXPECT_LT(0, rv); |
| 1623 #else |
| 1624 // NSS attempts to flush the write buffer in PR_Read on an SSL socket before |
| 1625 // pumping the read state machine, unless configured with SSL_ENABLE_FDX, so |
| 1626 // the write error bleeds into the read. |
1609 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1627 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1628 #endif |
1610 } | 1629 } |
1611 | 1630 |
1612 TEST_F(SSLClientSocketTest, Read_SmallChunks) { | 1631 TEST_F(SSLClientSocketTest, Read_SmallChunks) { |
1613 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1632 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
1614 SpawnedTestServer::kLocalhost, | 1633 SpawnedTestServer::kLocalhost, |
1615 base::FilePath()); | 1634 base::FilePath()); |
1616 ASSERT_TRUE(test_server.Start()); | 1635 ASSERT_TRUE(test_server.Start()); |
1617 | 1636 |
1618 AddressList addr; | 1637 AddressList addr; |
1619 ASSERT_TRUE(test_server.GetAddressList(&addr)); | 1638 ASSERT_TRUE(test_server.GetAddressList(&addr)); |
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2632 | 2651 |
2633 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns | 2652 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns |
2634 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all | 2653 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all |
2635 // error codes for now. | 2654 // error codes for now. |
2636 // http://crbug.com/373670 | 2655 // http://crbug.com/373670 |
2637 EXPECT_NE(OK, rv); | 2656 EXPECT_NE(OK, rv); |
2638 EXPECT_FALSE(sock_->IsConnected()); | 2657 EXPECT_FALSE(sock_->IsConnected()); |
2639 } | 2658 } |
2640 | 2659 |
2641 } // namespace net | 2660 } // namespace net |
OLD | NEW |