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

Side by Side Diff: net/quic/quic_crypto_client_stream.cc

Issue 154933003: Persist server's crypto config data to disk cache for 0-RTT (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Undid bad upload (had problems with git merge) Created 6 years, 10 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/quic/quic_crypto_client_stream.h" 5 #include "net/quic/quic_crypto_client_stream.h"
6 6
7 #include "net/base/completion_callback.h" 7 #include "net/base/completion_callback.h"
8 #include "net/base/net_errors.h" 8 #include "net/base/net_errors.h"
9 #include "net/quic/crypto/crypto_protocol.h" 9 #include "net/quic/crypto/crypto_protocol.h"
10 #include "net/quic/crypto/crypto_utils.h" 10 #include "net/quic/crypto/crypto_utils.h"
11 #include "net/quic/crypto/null_encrypter.h" 11 #include "net/quic/crypto/null_encrypter.h"
12 #include "net/quic/crypto/proof_verifier.h" 12 #include "net/quic/crypto/proof_verifier.h"
13 #include "net/quic/crypto/proof_verifier_chromium.h" 13 #include "net/quic/crypto/proof_verifier_chromium.h"
14 #include "net/quic/crypto/quic_server_info.h"
14 #include "net/quic/quic_protocol.h" 15 #include "net/quic/quic_protocol.h"
15 #include "net/quic/quic_session.h" 16 #include "net/quic/quic_session.h"
16 #include "net/ssl/ssl_connection_status_flags.h" 17 #include "net/ssl/ssl_connection_status_flags.h"
17 #include "net/ssl/ssl_info.h" 18 #include "net/ssl/ssl_info.h"
18 19
19 namespace net { 20 namespace net {
20 21
21 namespace { 22 namespace {
22 23
23 // Copies CertVerifyResult from |verify_details| to |cert_verify_result|. 24 // Copies CertVerifyResult from |verify_details| to |cert_verify_result|.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 QuicCryptoClientStream::QuicCryptoClientStream( 68 QuicCryptoClientStream::QuicCryptoClientStream(
68 const string& server_hostname, 69 const string& server_hostname,
69 QuicSession* session, 70 QuicSession* session,
70 QuicCryptoClientConfig* crypto_config) 71 QuicCryptoClientConfig* crypto_config)
71 : QuicCryptoStream(session), 72 : QuicCryptoStream(session),
72 next_state_(STATE_IDLE), 73 next_state_(STATE_IDLE),
73 num_client_hellos_(0), 74 num_client_hellos_(0),
74 crypto_config_(crypto_config), 75 crypto_config_(crypto_config),
75 server_hostname_(server_hostname), 76 server_hostname_(server_hostname),
76 generation_counter_(0), 77 generation_counter_(0),
77 proof_verify_callback_(NULL) { 78 proof_verify_callback_(NULL),
79 disk_cache_load_result_(ERR_UNEXPECTED) {
78 } 80 }
79 81
80 QuicCryptoClientStream::~QuicCryptoClientStream() { 82 QuicCryptoClientStream::~QuicCryptoClientStream() {
81 if (proof_verify_callback_) { 83 if (proof_verify_callback_) {
82 proof_verify_callback_->Cancel(); 84 proof_verify_callback_->Cancel();
83 } 85 }
84 } 86 }
85 87
86 void QuicCryptoClientStream::OnHandshakeMessage( 88 void QuicCryptoClientStream::OnHandshakeMessage(
87 const CryptoHandshakeMessage& message) { 89 const CryptoHandshakeMessage& message) {
88 QuicCryptoStream::OnHandshakeMessage(message); 90 QuicCryptoStream::OnHandshakeMessage(message);
89 91
90 DoHandshakeLoop(&message); 92 DoHandshakeLoop(&message);
91 } 93 }
92 94
93 bool QuicCryptoClientStream::CryptoConnect() { 95 bool QuicCryptoClientStream::CryptoConnect() {
94 next_state_ = STATE_SEND_CHLO; 96 next_state_ = STATE_LOAD_QUIC_SERVER_INFO;
95 DoHandshakeLoop(NULL); 97 DoHandshakeLoop(NULL);
96 return true; 98 return true;
97 } 99 }
98 100
99 int QuicCryptoClientStream::num_sent_client_hellos() const { 101 int QuicCryptoClientStream::num_sent_client_hellos() const {
100 return num_client_hellos_; 102 return num_client_hellos_;
101 } 103 }
102 104
103 // TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways 105 // TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways
104 // we learn about SSL info (sync vs async vs cached). 106 // we learn about SSL info (sync vs async vs cached).
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 crypto_config_->LookupOrCreate(server_hostname_); 154 crypto_config_->LookupOrCreate(server_hostname_);
153 155
154 if (in != NULL) { 156 if (in != NULL) {
155 DVLOG(1) << "Client: Received " << in->DebugString(); 157 DVLOG(1) << "Client: Received " << in->DebugString();
156 } 158 }
157 159
158 for (;;) { 160 for (;;) {
159 const State state = next_state_; 161 const State state = next_state_;
160 next_state_ = STATE_IDLE; 162 next_state_ = STATE_IDLE;
161 switch (state) { 163 switch (state) {
164 case STATE_LOAD_QUIC_SERVER_INFO: {
165 if (DoLoadQuicServerInfo(cached) == ERR_IO_PENDING) {
166 return;
167 }
168 break;
169 }
170 case STATE_LOAD_QUIC_SERVER_INFO_COMPLETE: {
171 DoLoadQuicServerInfoComplete(cached);
172 break;
173 }
162 case STATE_SEND_CHLO: { 174 case STATE_SEND_CHLO: {
163 // Send the client hello in plaintext. 175 // Send the client hello in plaintext.
164 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); 176 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE);
165 if (num_client_hellos_ > kMaxClientHellos) { 177 if (num_client_hellos_ > kMaxClientHellos) {
166 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); 178 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS);
167 return; 179 return;
168 } 180 }
169 num_client_hellos_++; 181 num_client_hellos_++;
170 182
171 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { 183 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 return; 399 return;
388 } 400 }
389 case STATE_IDLE: 401 case STATE_IDLE:
390 // This means that the peer sent us a message that we weren't expecting. 402 // This means that the peer sent us a message that we weren't expecting.
391 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); 403 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
392 return; 404 return;
393 } 405 }
394 } 406 }
395 } 407 }
396 408
409 void QuicCryptoClientStream::OnIOComplete(int result) {
410 DCHECK_EQ(STATE_LOAD_QUIC_SERVER_INFO_COMPLETE, next_state_);
411 DCHECK_NE(ERR_IO_PENDING, result);
412 disk_cache_load_result_ = result;
413 DoHandshakeLoop(NULL);
414 }
415
416 int QuicCryptoClientStream::DoLoadQuicServerInfo(
417 QuicCryptoClientConfig::CachedState* cached) {
418 next_state_ = STATE_SEND_CHLO;
419 QuicServerInfo* quic_server_info = cached->quic_server_info();
420 if (!quic_server_info) {
421 return OK;
422 }
423
424 disk_cache_load_result_ = OK;
wtc 2014/02/19 22:53:28 This probably should be initialized to ERR_UNEXPEC
ramant (doing other things) 2014/02/20 02:34:06 Done.
425 generation_counter_ = cached->generation_counter();
426 next_state_ = STATE_LOAD_QUIC_SERVER_INFO_COMPLETE;
427
428 // TODO(rtenneti): If multiple tabs load the same URL, all requests except for
429 // the first request send InchoateClientHello. Fix the code to handle multiple
430 // requests. A possible solution is to wait for the first request to finish
431 // and use the data from the disk cache for all requests.
432 // We always call WaitForDataReady, so that we can save server config to disk
433 // cache, though we might have already loaded server config from a canonical
434 // config.
wtc 2014/02/19 22:53:28 This comment ("We always call WaitForDataReady, ..
ramant (doing other things) 2014/02/20 02:34:06 Done.
435 int rv = quic_server_info->WaitForDataReady(
436 base::Bind(&QuicCryptoClientStream::OnIOComplete,
437 base::Unretained(this)));
438
439 if (rv != ERR_IO_PENDING) {
440 disk_cache_load_result_ = rv;
441 }
442 return rv;
443 }
444
445 void QuicCryptoClientStream::DoLoadQuicServerInfoComplete(
446 QuicCryptoClientConfig::CachedState* cached) {
447 next_state_ = STATE_SEND_CHLO;
448
449 // Check if generation_counter has changed between STATE_LOAD_QUIC_SERVER_INFO
450 // and STATE_LOAD_QUIC_SERVER_INFO_COMPLETE state changes.
451 // TODO(rtenneti): Do we need generation_counter_? Could we just call
452 // cached->IsEmpty() (sever_config might have been filled with server config
453 // information from canonical server config)?
wtc 2014/02/19 22:53:28 If |cached| becomes non-empty but the generation c
ramant (doing other things) 2014/02/20 02:34:06 Done.
454 if (generation_counter_ != cached->generation_counter() ||
455 !cached->IsEmpty()) {
456 // Someone else has already saved a server config received from the network.
wtc 2014/02/19 22:53:28 This comment should say "from the network or the c
ramant (doing other things) 2014/02/20 02:34:06 Done.
457 return;
458 }
459
460 if (disk_cache_load_result_ != OK || !cached->LoadQuicServerInfo(
461 session()->connection()->clock()->WallNow())) {
462 // It is ok to proceed to STATE_SEND_CHLO when we cannot load QuicServerInfo
463 // from the disk cache.
464 DCHECK(cached->IsEmpty());
465 DVLOG(1) << "Empty server_config";
466 return;
467 }
468
469 ProofVerifier* verifier = crypto_config_->proof_verifier();
470 if (!verifier) {
471 // If no verifier is set then we don't check the certificates.
472 cached->SetProofValid();
473 } else if (!cached->signature().empty()) {
474 next_state_ = STATE_VERIFY_PROOF;
475 }
476 }
477
397 } // namespace net 478 } // namespace net
OLDNEW
« net/quic/crypto/quic_crypto_client_config.cc ('K') | « net/quic/quic_crypto_client_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698