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

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: Deleted unused data_loaded_ member 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 85 }
85 86
86 void QuicCryptoClientStream::OnHandshakeMessage( 87 void QuicCryptoClientStream::OnHandshakeMessage(
87 const CryptoHandshakeMessage& message) { 88 const CryptoHandshakeMessage& message) {
88 QuicCryptoStream::OnHandshakeMessage(message); 89 QuicCryptoStream::OnHandshakeMessage(message);
89 90
90 DoHandshakeLoop(&message); 91 DoHandshakeLoop(&message);
91 } 92 }
92 93
93 bool QuicCryptoClientStream::CryptoConnect() { 94 bool QuicCryptoClientStream::CryptoConnect() {
94 next_state_ = STATE_SEND_CHLO; 95 next_state_ = STATE_LOAD_QUIC_SERVER_INFO;
95 DoHandshakeLoop(NULL); 96 DoHandshakeLoop(NULL);
96 return true; 97 return true;
97 } 98 }
98 99
99 int QuicCryptoClientStream::num_sent_client_hellos() const { 100 int QuicCryptoClientStream::num_sent_client_hellos() const {
100 return num_client_hellos_; 101 return num_client_hellos_;
101 } 102 }
102 103
103 // TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways 104 // TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways
104 // we learn about SSL info (sync vs async vs cached). 105 // 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_); 153 crypto_config_->LookupOrCreate(server_hostname_);
153 154
154 if (in != NULL) { 155 if (in != NULL) {
155 DVLOG(1) << "Client: Received " << in->DebugString(); 156 DVLOG(1) << "Client: Received " << in->DebugString();
156 } 157 }
157 158
158 for (;;) { 159 for (;;) {
159 const State state = next_state_; 160 const State state = next_state_;
160 next_state_ = STATE_IDLE; 161 next_state_ = STATE_IDLE;
161 switch (state) { 162 switch (state) {
163 case STATE_LOAD_QUIC_SERVER_INFO: {
164 if (DoLoadQuicServerInfo(cached) == ERR_IO_PENDING) {
165 return;
166 }
167 break;
168 }
169 case STATE_LOAD_QUIC_SERVER_INFO_COMPLETE: {
170 DoLoadQuicServerInfoComplete(cached);
171 DCHECK_EQ(STATE_SEND_CHLO, next_state_);
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 }
181 if (!cached->proof_valid()) {
182 ProofVerifier* verifier = crypto_config_->proof_verifier();
183 if (!verifier) {
184 // If no verifier is set then we don't check the certificates.
185 cached->SetProofValid();
186 } else if (!cached->signature().empty()) {
187 next_state_ = STATE_VERIFY_PROOF;
188 break;
189 }
190 }
wtc 2014/02/11 01:01:45 I think this (lines 181-190) should be moved to Do
ramant (doing other things) 2014/02/11 07:57:55 Done.
169 num_client_hellos_++; 191 num_client_hellos_++;
170 192
171 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { 193 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
172 crypto_config_->FillInchoateClientHello( 194 crypto_config_->FillInchoateClientHello(
173 server_hostname_, 195 server_hostname_,
174 session()->connection()->supported_versions().front(), 196 session()->connection()->supported_versions().front(),
175 cached, &crypto_negotiated_params_, &out); 197 cached, &crypto_negotiated_params_, &out);
176 // Pad the inchoate client hello to fill up a packet. 198 // Pad the inchoate client hello to fill up a packet.
177 const size_t kFramingOverhead = 50; // A rough estimate. 199 const size_t kFramingOverhead = 50; // A rough estimate.
178 const size_t max_packet_size = 200 const size_t max_packet_size =
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); 333 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
312 return; 334 return;
313 } 335 }
314 // Check if generation_counter has changed between STATE_VERIFY_PROOF 336 // Check if generation_counter has changed between STATE_VERIFY_PROOF
315 // and STATE_VERIFY_PROOF_COMPLETE state changes. 337 // and STATE_VERIFY_PROOF_COMPLETE state changes.
316 if (generation_counter_ != cached->generation_counter()) { 338 if (generation_counter_ != cached->generation_counter()) {
317 next_state_ = STATE_VERIFY_PROOF; 339 next_state_ = STATE_VERIFY_PROOF;
318 } else { 340 } else {
319 cached->SetProofValid(); 341 cached->SetProofValid();
320 cached->SetProofVerifyDetails(verify_details_.release()); 342 cached->SetProofVerifyDetails(verify_details_.release());
343 cached->SaveQuicServerInfo();
wtc 2014/02/11 01:01:45 We should also call cached->SaveQuicServerInfo() w
ramant (doing other things) 2014/02/11 07:57:55 Done.
321 next_state_ = STATE_SEND_CHLO; 344 next_state_ = STATE_SEND_CHLO;
322 } 345 }
323 break; 346 break;
324 case STATE_RECV_SHLO: { 347 case STATE_RECV_SHLO: {
325 // We sent a CHLO that we expected to be accepted and now we're hoping 348 // We sent a CHLO that we expected to be accepted and now we're hoping
326 // for a SHLO from the server to confirm that. 349 // for a SHLO from the server to confirm that.
327 if (in->tag() == kREJ) { 350 if (in->tag() == kREJ) {
328 // alternative_decrypter will be NULL if the original alternative 351 // alternative_decrypter will be NULL if the original alternative
329 // decrypter latched and became the primary decrypter. That happens 352 // decrypter latched and became the primary decrypter. That happens
330 // if we received a message encrypted with the INITIAL key. 353 // if we received a message encrypted with the INITIAL key.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 return; 410 return;
388 } 411 }
389 case STATE_IDLE: 412 case STATE_IDLE:
390 // This means that the peer sent us a message that we weren't expecting. 413 // This means that the peer sent us a message that we weren't expecting.
391 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); 414 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
392 return; 415 return;
393 } 416 }
394 } 417 }
395 } 418 }
396 419
420 void QuicCryptoClientStream::OnIOComplete(int result) {
421 DCHECK_EQ(STATE_LOAD_QUIC_SERVER_INFO, next_state_);
wtc 2014/02/11 01:01:45 next_state_ should be STATE_LOAD_QUIC_SERVER_INFO_
ramant (doing other things) 2014/02/11 07:57:55 Done.
422 DCHECK_NE(ERR_IO_PENDING, result);
423 if (result != OK) {
424 next_state_ = STATE_SEND_CHLO;
425 } else {
426 next_state_ = STATE_LOAD_QUIC_SERVER_INFO_COMPLETE;
427 }
wtc 2014/02/11 01:01:45 Lines 423-427 should be deleted. Since DoHandshak
ramant (doing other things) 2014/02/11 07:57:55 Done.
428 DoHandshakeLoop(NULL);
429 }
430
431 int QuicCryptoClientStream::DoLoadQuicServerInfo(
432 QuicCryptoClientConfig::CachedState* cached) {
433 next_state_ = STATE_SEND_CHLO;
434 QuicServerInfo* quic_server_info = cached->quic_server_info();
435 if (!quic_server_info) {
436 return OK;
437 }
438
439 // TODO(rtenneti): If multiple tabs load the same URL, all requests except for
440 // the first request send InchoateClientHello. Fix the code to handle multiple
441 // requests. A possible solution is to wait for the first request to finish
442 // and use the data from the disk cache for all requests.
443 int rv = quic_server_info->WaitForDataReady(
wtc 2014/02/11 01:01:45 We probably should save the generation count of |c
ramant (doing other things) 2014/02/11 07:57:55 Done.
444 base::Bind(&QuicCryptoClientStream::OnIOComplete,
445 base::Unretained(this)));
446
447 if (rv != OK) {
448 if (rv == ERR_IO_PENDING) {
449 next_state_ = STATE_LOAD_QUIC_SERVER_INFO;
wtc 2014/02/11 01:01:45 This should be STATE_LOAD_QUIC_SERVER_INFO_COMPLET
ramant (doing other things) 2014/02/11 07:57:55 Done.
450 return rv;
451 }
452 // It is ok to proceed to STATE_SEND_CHLO when we cannot load QuicServerInfo
453 // from the disk cache.
454 DVLOG(1) << "QuicServerInfo's WaitForDataReady failed";
455 }
456 return OK;
457 }
458
459 void QuicCryptoClientStream::DoLoadQuicServerInfoComplete(
460 QuicCryptoClientConfig::CachedState* cached) {
461 next_state_ = STATE_SEND_CHLO;
462
463 if (!cached->quic_server_info()->IsDataReady()) {
wtc 2014/02/11 01:01:45 We probably need to check the generation count her
ramant (doing other things) 2014/02/11 07:57:55 Done.
464 // It is ok to proceed to STATE_SEND_CHLO when we cannot load QuicServerInfo
465 // from the disk cache.
466 DVLOG(1) << "Loading of QuicServerInfo failed";
467 return;
468 }
469
470 cached->LoadQuicServerInfo();
471
472 return;
473 }
474
397 } // namespace net 475 } // namespace net
OLDNEW
« net/quic/crypto/quic_server_info.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