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

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

Issue 208293002: Add False Start tests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase to trunk. Created 6 years, 8 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 | « no previous file | net/test/spawned_test_server/base_test_server.h » ('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) 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 "net/base/address_list.h" 10 #include "net/base/address_list.h"
10 #include "net/base/io_buffer.h" 11 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
12 #include "net/base/net_log.h" 13 #include "net/base/net_log.h"
13 #include "net/base/net_log_unittest.h" 14 #include "net/base/net_log_unittest.h"
14 #include "net/base/test_completion_callback.h" 15 #include "net/base/test_completion_callback.h"
15 #include "net/base/test_data_directory.h" 16 #include "net/base/test_data_directory.h"
16 #include "net/cert/mock_cert_verifier.h" 17 #include "net/cert/mock_cert_verifier.h"
17 #include "net/cert/test_root_certs.h" 18 #include "net/cert/test_root_certs.h"
18 #include "net/dns/host_resolver.h" 19 #include "net/dns/host_resolver.h"
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 // deterministic manner (e.g.: independent of the TestServer and the OS's 321 // deterministic manner (e.g.: independent of the TestServer and the OS's
321 // semantics). 322 // semantics).
322 class FakeBlockingStreamSocket : public WrappedStreamSocket { 323 class FakeBlockingStreamSocket : public WrappedStreamSocket {
323 public: 324 public:
324 explicit FakeBlockingStreamSocket(scoped_ptr<StreamSocket> transport); 325 explicit FakeBlockingStreamSocket(scoped_ptr<StreamSocket> transport);
325 virtual ~FakeBlockingStreamSocket() {} 326 virtual ~FakeBlockingStreamSocket() {}
326 327
327 // Socket implementation: 328 // Socket implementation:
328 virtual int Read(IOBuffer* buf, 329 virtual int Read(IOBuffer* buf,
329 int buf_len, 330 int buf_len,
330 const CompletionCallback& callback) OVERRIDE { 331 const CompletionCallback& callback) OVERRIDE;
331 return read_state_.RunWrappedFunction(buf, buf_len, callback);
332 }
333 virtual int Write(IOBuffer* buf, 332 virtual int Write(IOBuffer* buf,
334 int buf_len, 333 int buf_len,
335 const CompletionCallback& callback) OVERRIDE { 334 const CompletionCallback& callback) OVERRIDE;
336 return write_state_.RunWrappedFunction(buf, buf_len, callback);
337 }
338 335
339 // Causes the next call to Read() to return ERR_IO_PENDING, not completing 336 // Causes the next call to Read() to return ERR_IO_PENDING, not completing
340 // (invoking the callback) until UnblockRead() has been called and the 337 // (invoking the callback) until UnblockRead() has been called and the
341 // underlying transport has completed. 338 // underlying transport has completed.
342 void SetNextReadShouldBlock() { read_state_.SetShouldBlock(); } 339 void SetNextReadShouldBlock();
343 void UnblockRead() { read_state_.Unblock(); } 340 void UnblockRead();
344 341
345 // Causes the next call to Write() to return ERR_IO_PENDING, not completing 342 // Waits for the blocked Read() call to be complete at the underlying
346 // (invoking the callback) until UnblockWrite() has been called and the 343 // transport.
347 // underlying transport has completed. 344 void WaitForRead();
348 void SetNextWriteShouldBlock() { write_state_.SetShouldBlock(); } 345
349 void UnblockWrite() { write_state_.Unblock(); } 346 // Causes the next call to Write() to return ERR_IO_PENDING, not beginning the
347 // underlying transport until UnblockWrite() has been called.
348 void SetNextWriteShouldBlock();
349 void UnblockWrite();
350
351 // Waits for the blocked Write() call to be scheduled.
352 void WaitForWrite();
350 353
351 private: 354 private:
352 // Tracks the state for simulating a blocking Read/Write operation. 355 // Handles completion from the underlying transport read.
353 class BlockingState { 356 void OnReadCompleted(int result);
354 public:
355 // Wrapper for the underlying Socket function to call (ie: Read/Write).
356 typedef base::Callback<int(IOBuffer*, int, const CompletionCallback&)>
357 WrappedSocketFunction;
358 357
359 explicit BlockingState(const WrappedSocketFunction& function); 358 // True if read callbacks are blocked.
360 ~BlockingState() {} 359 bool should_block_read_;
361 360
362 // Sets the next call to RunWrappedFunction() to block, returning 361 // The user callback for the pending read call.
363 // ERR_IO_PENDING and not invoking the user callback until Unblock() is 362 CompletionCallback pending_read_callback_;
364 // called.
365 void SetShouldBlock();
366 363
367 // Unblocks the currently blocked pending function, invoking the user 364 // The result for the blocked read callback, or ERR_IO_PENDING if not
368 // callback if the results are immediately available. 365 // completed.
369 // Note: It's not valid to call this unless SetShouldBlock() has been 366 int pending_read_result_;
370 // called beforehand.
371 void Unblock();
372 367
373 // Performs the wrapped socket function on the underlying transport. If 368 // WaitForRead() wait loop.
374 // configured to block via SetShouldBlock(), then |user_callback| will not 369 scoped_ptr<base::RunLoop> read_loop_;
375 // be invoked until Unblock() has been called.
376 int RunWrappedFunction(IOBuffer* buf,
377 int len,
378 const CompletionCallback& user_callback);
379 370
380 private: 371 // True if write calls are blocked.
381 // Handles completion from the underlying wrapped socket function. 372 bool should_block_write_;
382 void OnCompleted(int result);
383 373
384 WrappedSocketFunction wrapped_function_; 374 // The buffer for the pending write, or NULL if not scheduled.
385 bool should_block_; 375 scoped_refptr<IOBuffer> pending_write_buf_;
386 bool have_result_;
387 int pending_result_;
388 CompletionCallback user_callback_;
389 };
390 376
391 BlockingState read_state_; 377 // The callback for the pending write call.
392 BlockingState write_state_; 378 CompletionCallback pending_write_callback_;
393 379
394 DISALLOW_COPY_AND_ASSIGN(FakeBlockingStreamSocket); 380 // The length for the pending write, or -1 if not scheduled.
381 int pending_write_len_;
382
383 // WaitForWrite() wait loop.
384 scoped_ptr<base::RunLoop> write_loop_;
395 }; 385 };
396 386
397 FakeBlockingStreamSocket::FakeBlockingStreamSocket( 387 FakeBlockingStreamSocket::FakeBlockingStreamSocket(
398 scoped_ptr<StreamSocket> transport) 388 scoped_ptr<StreamSocket> transport)
399 : WrappedStreamSocket(transport.Pass()), 389 : WrappedStreamSocket(transport.Pass()),
400 read_state_(base::Bind(&Socket::Read, 390 should_block_read_(false),
401 base::Unretained(transport_.get()))), 391 pending_read_result_(ERR_IO_PENDING),
402 write_state_(base::Bind(&Socket::Write, 392 should_block_write_(false),
403 base::Unretained(transport_.get()))) {} 393 pending_write_len_(-1) {}
404 394
405 FakeBlockingStreamSocket::BlockingState::BlockingState( 395 int FakeBlockingStreamSocket::Read(IOBuffer* buf,
406 const WrappedSocketFunction& function) 396 int len,
407 : wrapped_function_(function), 397 const CompletionCallback& callback) {
408 should_block_(false), 398 if (!should_block_read_)
409 have_result_(false), 399 return transport_->Read(buf, len, callback);
410 pending_result_(OK) {}
411 400
412 void FakeBlockingStreamSocket::BlockingState::SetShouldBlock() { 401 DCHECK(pending_read_callback_.is_null());
413 DCHECK(!should_block_); 402 DCHECK_EQ(ERR_IO_PENDING, pending_read_result_);
414 should_block_ = true; 403
404 int rv = transport_->Read(buf, len, base::Bind(
405 &FakeBlockingStreamSocket::OnReadCompleted, base::Unretained(this)));
406 if (rv == ERR_IO_PENDING) {
407 pending_read_callback_ = callback;
408 } else {
409 OnReadCompleted(rv);
410 }
411 return ERR_IO_PENDING;
415 } 412 }
416 413
417 void FakeBlockingStreamSocket::BlockingState::Unblock() { 414 int FakeBlockingStreamSocket::Write(IOBuffer* buf,
418 DCHECK(should_block_); 415 int len,
419 should_block_ = false; 416 const CompletionCallback& callback) {
417 DCHECK(buf);
418 DCHECK_LE(0, len);
419
420 if (!should_block_write_)
421 return transport_->Write(buf, len, callback);
422
423 // Schedule the write, but do nothing.
424 DCHECK(!pending_write_buf_);
425 DCHECK_EQ(-1, pending_write_len_);
426 DCHECK(pending_write_callback_.is_null());
427 pending_write_buf_ = buf;
428 pending_write_len_ = len;
429 pending_write_callback_ = callback;
430
431 // Stop the write loop, if any.
432 if (write_loop_)
433 write_loop_->Quit();
434 return ERR_IO_PENDING;
435 }
436
437 void FakeBlockingStreamSocket::SetNextReadShouldBlock() {
438 DCHECK(!should_block_read_);
439 should_block_read_ = true;
440 }
441
442 void FakeBlockingStreamSocket::UnblockRead() {
443 DCHECK(should_block_read_);
444 should_block_read_ = false;
420 445
421 // If the operation is still pending in the underlying transport, immediately 446 // If the operation is still pending in the underlying transport, immediately
422 // return - OnCompleted() will handle invoking the callback once the transport 447 // return - OnReadCompleted() will handle invoking the callback once the
423 // has completed. 448 // transport has completed.
424 if (!have_result_) 449 if (pending_read_result_ == ERR_IO_PENDING)
450 return;
451 int result = pending_read_result_;
452 pending_read_result_ = ERR_IO_PENDING;
453 base::ResetAndReturn(&pending_read_callback_).Run(result);
454 }
455
456 void FakeBlockingStreamSocket::WaitForRead() {
457 DCHECK(should_block_read_);
458 DCHECK(!read_loop_);
459
460 if (pending_read_result_ != ERR_IO_PENDING)
461 return;
462 read_loop_.reset(new base::RunLoop);
463 read_loop_->Run();
464 read_loop_.reset();
465 DCHECK_NE(ERR_IO_PENDING, pending_read_result_);
466 }
467
468 void FakeBlockingStreamSocket::SetNextWriteShouldBlock() {
469 DCHECK(!should_block_write_);
470 should_block_write_ = true;
471 }
472
473 void FakeBlockingStreamSocket::UnblockWrite() {
474 DCHECK(should_block_write_);
475 should_block_write_ = false;
476
477 // Do nothing if UnblockWrite() was called after SetNextWriteShouldBlock(),
478 // without a Write() in between.
479 if (!pending_write_buf_)
425 return; 480 return;
426 481
427 have_result_ = false; 482 int rv = transport_->Write(pending_write_buf_, pending_write_len_,
428 483 pending_write_callback_);
429 base::ResetAndReturn(&user_callback_).Run(pending_result_); 484 pending_write_buf_ = NULL;
485 pending_write_len_ = -1;
486 if (rv == ERR_IO_PENDING) {
487 pending_write_callback_.Reset();
488 } else {
489 base::ResetAndReturn(&pending_write_callback_).Run(rv);
490 }
430 } 491 }
431 492
432 int FakeBlockingStreamSocket::BlockingState::RunWrappedFunction( 493 void FakeBlockingStreamSocket::WaitForWrite() {
433 IOBuffer* buf, 494 DCHECK(should_block_write_);
434 int len, 495 DCHECK(!write_loop_);
435 const CompletionCallback& callback) {
436 496
437 // The callback to be called by the underlying transport. Either forward 497 if (pending_write_buf_)
438 // directly to the user's callback if not set to block, or intercept it with 498 return;
439 // OnCompleted so that the user's callback is not invoked until Unblock() is 499 write_loop_.reset(new base::RunLoop);
440 // called. 500 write_loop_->Run();
441 CompletionCallback transport_callback = 501 write_loop_.reset();
442 !should_block_ ? callback : base::Bind(&BlockingState::OnCompleted, 502 DCHECK(pending_write_buf_);
443 base::Unretained(this));
444 int rv = wrapped_function_.Run(buf, len, transport_callback);
445 if (should_block_) {
446 user_callback_ = callback;
447 // May have completed synchronously.
448 have_result_ = (rv != ERR_IO_PENDING);
449 pending_result_ = rv;
450 return ERR_IO_PENDING;
451 }
452
453 return rv;
454 } 503 }
455 504
456 void FakeBlockingStreamSocket::BlockingState::OnCompleted(int result) { 505 void FakeBlockingStreamSocket::OnReadCompleted(int result) {
457 if (should_block_) { 506 if (should_block_read_) {
458 // Store the result so that the callback can be invoked once Unblock() is 507 // Store the result so that the callback can be invoked once Unblock() is
459 // called. 508 // called.
460 have_result_ = true; 509 pending_read_result_ = result;
461 pending_result_ = result; 510
511 // Stop the WaitForRead() call if any.
512 if (read_loop_)
513 read_loop_->Quit();
462 return; 514 return;
463 } 515 }
464 516
465 // Otherwise, the Unblock() function was called before the underlying 517 // Otherwise, the Unblock() function was called before the underlying
466 // transport completed, so run the user's callback immediately. 518 // transport completed, so run the user's callback immediately.
467 base::ResetAndReturn(&user_callback_).Run(result); 519 base::ResetAndReturn(&pending_read_callback_).Run(result);
468 } 520 }
469 521
470 // CompletionCallback that will delete the associated StreamSocket when 522 // CompletionCallback that will delete the associated StreamSocket when
471 // the callback is invoked. 523 // the callback is invoked.
472 class DeleteSocketCallback : public TestCompletionCallbackBase { 524 class DeleteSocketCallback : public TestCompletionCallbackBase {
473 public: 525 public:
474 explicit DeleteSocketCallback(StreamSocket* socket) 526 explicit DeleteSocketCallback(StreamSocket* socket)
475 : socket_(socket), 527 : socket_(socket),
476 callback_(base::Bind(&DeleteSocketCallback::OnComplete, 528 callback_(base::Bind(&DeleteSocketCallback::OnComplete,
477 base::Unretained(this))) {} 529 base::Unretained(this))) {}
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 rv = callback.WaitForResult(); 610 rv = callback.WaitForResult();
559 scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo(); 611 scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo();
560 sock->GetSSLCertRequestInfo(request_info.get()); 612 sock->GetSSLCertRequestInfo(request_info.get());
561 sock->Disconnect(); 613 sock->Disconnect();
562 EXPECT_FALSE(sock->IsConnected()); 614 EXPECT_FALSE(sock->IsConnected());
563 615
564 return request_info; 616 return request_info;
565 } 617 }
566 }; 618 };
567 619
620 class SSLClientSocketFalseStartTest : public SSLClientSocketTest {
621 protected:
622 void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options,
623 const SSLConfig& client_config,
624 bool expect_false_start) {
625 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
626 server_options,
627 base::FilePath());
628 ASSERT_TRUE(test_server.Start());
629
630 AddressList addr;
631 ASSERT_TRUE(test_server.GetAddressList(&addr));
632
633 TestCompletionCallback callback;
634 scoped_ptr<StreamSocket> real_transport(
635 new TCPClientSocket(addr, NULL, NetLog::Source()));
636 scoped_ptr<FakeBlockingStreamSocket> transport(
637 new FakeBlockingStreamSocket(real_transport.Pass()));
638 int rv = callback.GetResult(transport->Connect(callback.callback()));
639 EXPECT_EQ(OK, rv);
640
641 FakeBlockingStreamSocket* raw_transport = transport.get();
642 scoped_ptr<SSLClientSocket> sock(
643 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
644 test_server.host_port_pair(),
645 client_config));
646
647 // Connect. Stop before the client processes the first server leg
648 // (ServerHello, etc.)
649 raw_transport->SetNextReadShouldBlock();
650 rv = sock->Connect(callback.callback());
651 EXPECT_EQ(ERR_IO_PENDING, rv);
652 raw_transport->WaitForRead();
653
654 // Release the ServerHello and wait for the client to write
655 // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the
656 // server's leg to complete, since it may span multiple reads.)
657 EXPECT_FALSE(callback.have_result());
658 raw_transport->SetNextWriteShouldBlock();
659 raw_transport->UnblockRead();
660 raw_transport->WaitForWrite();
661
662 // And, finally, release that and block the next server leg
663 // (ChangeCipherSpec, Finished). Note: callback.have_result() may or may not
664 // be true at this point depending on whether the SSL implementation waits
665 // for the client second leg to clear the internal write buffer and hit the
666 // network.
667 raw_transport->SetNextReadShouldBlock();
668 raw_transport->UnblockWrite();
669
670 if (expect_false_start) {
671 // When False Starting, the handshake should complete before receiving the
672 // Change Cipher Spec and Finished messages.
673 rv = callback.GetResult(rv);
674 EXPECT_EQ(OK, rv);
675 EXPECT_TRUE(sock->IsConnected());
676
677 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
678 static const int kRequestTextSize =
679 static_cast<int>(arraysize(request_text) - 1);
680 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize));
681 memcpy(request_buffer->data(), request_text, kRequestTextSize);
682
683 // Write the request.
684 rv = callback.GetResult(sock->Write(request_buffer.get(),
685 kRequestTextSize,
686 callback.callback()));
687 EXPECT_EQ(kRequestTextSize, rv);
688
689 // The read will hang; it's waiting for the peer to complete the
690 // handshake, and the handshake is still blocked.
691 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
692 rv = sock->Read(buf.get(), 4096, callback.callback());
693
694 // After releasing reads, the connection proceeds.
695 raw_transport->UnblockRead();
696 rv = callback.GetResult(rv);
697 EXPECT_LT(0, rv);
698 } else {
699 // False Start is not enabled, so the handshake will not complete because
700 // the server second leg is blocked.
701 base::RunLoop().RunUntilIdle();
702 EXPECT_FALSE(callback.have_result());
703 }
704 }
705 };
706
568 //----------------------------------------------------------------------------- 707 //-----------------------------------------------------------------------------
569 708
570 // LogContainsSSLConnectEndEvent returns true if the given index in the given 709 // LogContainsSSLConnectEndEvent returns true if the given index in the given
571 // log is an SSL connect end event. The NSS sockets will cork in an attempt to 710 // log is an SSL connect end event. The NSS sockets will cork in an attempt to
572 // merge the first application data record with the Finished message when false 711 // merge the first application data record with the Finished message when false
573 // starting. However, in order to avoid the server timing out the handshake, 712 // starting. However, in order to avoid the server timing out the handshake,
574 // they'll give up waiting for application data and send the Finished after a 713 // they'll give up waiting for application data and send the Finished after a
575 // timeout. This means that an SSL connect end event may appear as a socket 714 // timeout. This means that an SSL connect end event may appear as a socket
576 // write. 715 // write.
577 static bool LogContainsSSLConnectEndEvent( 716 static bool LogContainsSSLConnectEndEvent(
(...skipping 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after
2176 EXPECT_TRUE(sock->WasEverUsed()); 2315 EXPECT_TRUE(sock->WasEverUsed());
2177 2316
2178 // TODO(davidben): Read one byte to ensure the test server has responded and 2317 // TODO(davidben): Read one byte to ensure the test server has responded and
2179 // then assert IsConnectedAndIdle is false. This currently doesn't work 2318 // then assert IsConnectedAndIdle is false. This currently doesn't work
2180 // because neither SSLClientSocketNSS nor SSLClientSocketOpenSSL check their 2319 // because neither SSLClientSocketNSS nor SSLClientSocketOpenSSL check their
2181 // SSL implementation's internal buffers. Either call PR_Available and 2320 // SSL implementation's internal buffers. Either call PR_Available and
2182 // SSL_pending, although the former isn't actually implemented or perhaps 2321 // SSL_pending, although the former isn't actually implemented or perhaps
2183 // attempt to read one byte extra. 2322 // attempt to read one byte extra.
2184 } 2323 }
2185 2324
2325 // This test is only enabled on NSS until False Start support is added for
2326 // OpenSSL. http://crbug.com/354132
2327 #if defined(USE_NSS)
2328 #define MAYBE_FalseStartEnabled FalseStartEnabled
2329 #else
2330 #define MAYBE_FalseStartEnabled DISABLED_FalseStartEnabled
2331 #endif // USE_NSS
2332 TEST_F(SSLClientSocketFalseStartTest, MAYBE_FalseStartEnabled) {
2333 // False Start requires NPN and a forward-secret cipher suite.
2334 SpawnedTestServer::SSLOptions server_options;
2335 server_options.key_exchanges =
2336 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2337 server_options.enable_npn = true;
2338 SSLConfig client_config;
2339 client_config.next_protos.push_back("http/1.1");
2340 TestFalseStart(server_options, client_config, true);
2341 }
2342
2343 // Test that False Start is disabled without NPN.
2344 TEST_F(SSLClientSocketFalseStartTest, NoNPN) {
2345 SpawnedTestServer::SSLOptions server_options;
2346 server_options.key_exchanges =
2347 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
2348 SSLConfig client_config;
2349 client_config.next_protos.clear();
2350 TestFalseStart(server_options, client_config, false);
2351 }
2352
2353 // Test that False Start is disabled without a forward-secret cipher suite.
2354 TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) {
2355 SpawnedTestServer::SSLOptions server_options;
2356 server_options.key_exchanges =
2357 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA;
2358 server_options.enable_npn = true;
2359 SSLConfig client_config;
2360 client_config.next_protos.push_back("http/1.1");
2361 TestFalseStart(server_options, client_config, false);
2362 }
2363
2186 } // namespace net 2364 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/test/spawned_test_server/base_test_server.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698