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

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

Issue 367963007: Preserve transport errors for OpenSSL sockets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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
OLDNEW
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 "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 1239
1240 if (rv == ERR_IO_PENDING) 1240 if (rv == ERR_IO_PENDING)
1241 rv = callback.WaitForResult(); 1241 rv = callback.WaitForResult();
1242 1242
1243 EXPECT_GE(rv, 0); 1243 EXPECT_GE(rv, 0);
1244 if (rv <= 0) 1244 if (rv <= 0)
1245 break; 1245 break;
1246 } 1246 }
1247 } 1247 }
1248 1248
1249 // Tests that SSLClientSocket properly handles when the underlying transport
1250 // synchronously fails a transport read in during the handshake. The error code
1251 // should be preserved so SSLv3 fallback logic can condition on it.
1252 TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) {
1253 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1254 SpawnedTestServer::kLocalhost,
1255 base::FilePath());
1256 ASSERT_TRUE(test_server.Start());
1257
1258 AddressList addr;
1259 ASSERT_TRUE(test_server.GetAddressList(&addr));
1260
1261 TestCompletionCallback callback;
1262 scoped_ptr<StreamSocket> real_transport(
1263 new TCPClientSocket(addr, NULL, NetLog::Source()));
1264 scoped_ptr<SynchronousErrorStreamSocket> transport(
1265 new SynchronousErrorStreamSocket(real_transport.Pass()));
1266 int rv = callback.GetResult(transport->Connect(callback.callback()));
1267 EXPECT_EQ(OK, rv);
1268
1269 // Disable TLS False Start to avoid handshake non-determinism.
1270 SSLConfig ssl_config;
1271 ssl_config.false_start_enabled = false;
1272
1273 SynchronousErrorStreamSocket* raw_transport = transport.get();
1274 scoped_ptr<SSLClientSocket> sock(
1275 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
1276 test_server.host_port_pair(),
1277 ssl_config));
1278
1279 raw_transport->SetNextWriteError(ERR_CONNECTION_RESET);
1280
1281 rv = callback.GetResult(sock->Connect(callback.callback()));
1282 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1283 EXPECT_FALSE(sock->IsConnected());
1284 }
1285
1249 // Tests that the SSLClientSocket properly handles when the underlying transport 1286 // Tests that the SSLClientSocket properly handles when the underlying transport
1250 // synchronously returns an error code - such as if an intermediary terminates 1287 // synchronously returns an error code - such as if an intermediary terminates
1251 // the socket connection uncleanly. 1288 // the socket connection uncleanly.
1252 // This is a regression test for http://crbug.com/238536 1289 // This is a regression test for http://crbug.com/238536
1253 TEST_F(SSLClientSocketTest, Read_WithSynchronousError) { 1290 TEST_F(SSLClientSocketTest, Read_WithSynchronousError) {
1254 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 1291 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1255 SpawnedTestServer::kLocalhost, 1292 SpawnedTestServer::kLocalhost,
1256 base::FilePath()); 1293 base::FilePath());
1257 ASSERT_TRUE(test_server.Start()); 1294 ASSERT_TRUE(test_server.Start());
1258 1295
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 1330
1294 // Simulate an unclean/forcible shutdown. 1331 // Simulate an unclean/forcible shutdown.
1295 raw_transport->SetNextReadError(ERR_CONNECTION_RESET); 1332 raw_transport->SetNextReadError(ERR_CONNECTION_RESET);
1296 1333
1297 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); 1334 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
1298 1335
1299 // Note: This test will hang if this bug has regressed. Simply checking that 1336 // Note: This test will hang if this bug has regressed. Simply checking that
1300 // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate 1337 // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate
1301 // result when using a dedicated task runner for NSS. 1338 // result when using a dedicated task runner for NSS.
1302 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); 1339 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback()));
1303
1304 #if !defined(USE_OPENSSL)
1305 // SSLClientSocketNSS records the error exactly
1306 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1340 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1307 #else
1308 // SSLClientSocketOpenSSL treats any errors as a simple EOF.
1309 EXPECT_EQ(0, rv);
1310 #endif
1311 } 1341 }
1312 1342
1313 // Tests that the SSLClientSocket properly handles when the underlying transport 1343 // Tests that the SSLClientSocket properly handles when the underlying transport
1314 // asynchronously returns an error code while writing data - such as if an 1344 // asynchronously returns an error code while writing data - such as if an
1315 // intermediary terminates the socket connection uncleanly. 1345 // intermediary terminates the socket connection uncleanly.
1316 // This is a regression test for http://crbug.com/249848 1346 // This is a regression test for http://crbug.com/249848
1317 TEST_F(SSLClientSocketTest, Write_WithSynchronousError) { 1347 TEST_F(SSLClientSocketTest, Write_WithSynchronousError) {
1318 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 1348 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1319 SpawnedTestServer::kLocalhost, 1349 SpawnedTestServer::kLocalhost,
1320 base::FilePath()); 1350 base::FilePath());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 EXPECT_EQ(ERR_IO_PENDING, rv); 1404 EXPECT_EQ(ERR_IO_PENDING, rv);
1375 1405
1376 // Now unblock the outgoing request, having it fail with the connection 1406 // Now unblock the outgoing request, having it fail with the connection
1377 // being reset. 1407 // being reset.
1378 raw_transport->UnblockWrite(); 1408 raw_transport->UnblockWrite();
1379 1409
1380 // Note: This will cause an inifite loop if this bug has regressed. Simply 1410 // Note: This will cause an inifite loop if this bug has regressed. Simply
1381 // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING 1411 // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING
1382 // is a legitimate result when using a dedicated task runner for NSS. 1412 // is a legitimate result when using a dedicated task runner for NSS.
1383 rv = callback.GetResult(rv); 1413 rv = callback.GetResult(rv);
1384
1385 #if !defined(USE_OPENSSL)
1386 // SSLClientSocketNSS records the error exactly
1387 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1414 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1388 #else
1389 // SSLClientSocketOpenSSL treats any errors as a simple EOF.
1390 EXPECT_EQ(0, rv);
1391 #endif
1392 } 1415 }
1393 1416
1394 // If there is a Write failure at the transport with no follow-up Read, although 1417 // If there is a Write failure at the transport with no follow-up Read, although
1395 // the write error will not be returned to the client until a future Read or 1418 // the write error will not be returned to the client until a future Read or
1396 // Write operation, SSLClientSocket should not spin attempting to re-write on 1419 // Write operation, SSLClientSocket should not spin attempting to re-write on
1397 // the socket. This is a regression test for part of https://crbug.com/381160. 1420 // the socket. This is a regression test for part of https://crbug.com/381160.
1398 TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) { 1421 TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) {
1399 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 1422 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1400 SpawnedTestServer::kLocalhost, 1423 SpawnedTestServer::kLocalhost,
1401 base::FilePath()); 1424 base::FilePath());
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 callback.callback()); 1647 callback.callback());
1625 ASSERT_EQ(ERR_IO_PENDING, rv); 1648 ASSERT_EQ(ERR_IO_PENDING, rv);
1626 ASSERT_FALSE(callback.have_result()); 1649 ASSERT_FALSE(callback.have_result());
1627 1650
1628 // Now unblock Write(), which will invoke OnSendComplete and (eventually) 1651 // Now unblock Write(), which will invoke OnSendComplete and (eventually)
1629 // call the Read() callback, deleting the socket and thus aborting calling 1652 // call the Read() callback, deleting the socket and thus aborting calling
1630 // the Write() callback. 1653 // the Write() callback.
1631 raw_transport->UnblockWrite(); 1654 raw_transport->UnblockWrite();
1632 1655
1633 rv = read_callback.WaitForResult(); 1656 rv = read_callback.WaitForResult();
1634
1635 #if !defined(USE_OPENSSL)
1636 // NSS records the error exactly.
1637 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1657 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1638 #else
1639 // OpenSSL treats any errors as a simple EOF.
1640 EXPECT_EQ(0, rv);
1641 #endif
1642 1658
1643 // The Write callback should not have been called. 1659 // The Write callback should not have been called.
1644 EXPECT_FALSE(callback.have_result()); 1660 EXPECT_FALSE(callback.have_result());
1645 } 1661 }
1646 1662
1647 // Tests that the SSLClientSocket does not crash if data is received on the 1663 // Tests that the SSLClientSocket does not crash if data is received on the
1648 // transport socket after a failing write. This can occur if we have a Write 1664 // transport socket after a failing write. This can occur if we have a Write
1649 // error in a SPDY socket. 1665 // error in a SPDY socket.
1650 // Regression test for http://crbug.com/335557 1666 // Regression test for http://crbug.com/335557
1651 TEST_F(SSLClientSocketTest, Read_WithWriteError) { 1667 TEST_F(SSLClientSocketTest, Read_WithWriteError) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 rv = callback.GetResult(sock->Write(long_request_buffer.get(), 1742 rv = callback.GetResult(sock->Write(long_request_buffer.get(),
1727 long_request_buffer->BytesRemaining(), 1743 long_request_buffer->BytesRemaining(),
1728 callback.callback())); 1744 callback.callback()));
1729 if (rv > 0) { 1745 if (rv > 0) {
1730 long_request_buffer->DidConsume(rv); 1746 long_request_buffer->DidConsume(rv);
1731 // Abort if the entire buffer is ever consumed. 1747 // Abort if the entire buffer is ever consumed.
1732 ASSERT_LT(0, long_request_buffer->BytesRemaining()); 1748 ASSERT_LT(0, long_request_buffer->BytesRemaining());
1733 } 1749 }
1734 } while (rv > 0); 1750 } while (rv > 0);
1735 1751
1736 #if !defined(USE_OPENSSL)
1737 // NSS records the error exactly.
1738 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1752 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1739 #else
1740 // OpenSSL treats the reset as a generic protocol error.
1741 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
1742 #endif
1743 1753
1744 // Release the read. Some bytes should go through. 1754 // Release the read.
1745 raw_transport->UnblockReadResult(); 1755 raw_transport->UnblockReadResult();
1746 rv = read_callback.WaitForResult(); 1756 rv = read_callback.WaitForResult();
1747 1757
1748 // Per the fix for http://crbug.com/249848, write failures currently break 1758 #if defined(USE_OPENSSL)
1749 // reads. Change this assertion if they're changed to not collide. 1759 // Should still read bytes despite the write error.
1760 EXPECT_LT(0, rv);
1761 #else
1762 // NSS attempts to flush the write buffer in PR_Read on an SSL socket before
1763 // pumping the read state machine, unless configured with SSL_ENABLE_FDX, so
1764 // the write error stops future reads.
Ryan Sleevi 2014/07/07 22:36:34 wtc: HERE
wtc 2014/07/09 15:55:27 I think we should fix this. This shouldn't be too
davidben 2014/07/09 16:00:08 I haven't looked at it much, apart from finding th
1750 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1765 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1766 #endif
1751 } 1767 }
1752 1768
1753 TEST_F(SSLClientSocketTest, Read_SmallChunks) { 1769 TEST_F(SSLClientSocketTest, Read_SmallChunks) {
1754 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 1770 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1755 SpawnedTestServer::kLocalhost, 1771 SpawnedTestServer::kLocalhost,
1756 base::FilePath()); 1772 base::FilePath());
1757 ASSERT_TRUE(test_server.Start()); 1773 ASSERT_TRUE(test_server.Start());
1758 1774
1759 AddressList addr; 1775 AddressList addr;
1760 ASSERT_TRUE(test_server.GetAddressList(&addr)); 1776 ASSERT_TRUE(test_server.GetAddressList(&addr));
(...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 ssl_config.channel_id_enabled = true; 2807 ssl_config.channel_id_enabled = true;
2792 2808
2793 int rv; 2809 int rv;
2794 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); 2810 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
2795 2811
2796 EXPECT_EQ(ERR_UNEXPECTED, rv); 2812 EXPECT_EQ(ERR_UNEXPECTED, rv);
2797 EXPECT_FALSE(sock_->IsConnected()); 2813 EXPECT_FALSE(sock_->IsConnected());
2798 } 2814 }
2799 2815
2800 } // namespace net 2816 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698