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/quic/quic_crypto_client_stream.h" | 5 #include "net/quic/quic_crypto_client_stream.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "net/base/completion_callback.h" | 8 #include "net/base/completion_callback.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "net/quic/crypto/crypto_protocol.h" | 10 #include "net/quic/crypto/crypto_protocol.h" |
11 #include "net/quic/crypto/crypto_utils.h" | 11 #include "net/quic/crypto/crypto_utils.h" |
12 #include "net/quic/crypto/null_encrypter.h" | 12 #include "net/quic/crypto/null_encrypter.h" |
13 #include "net/quic/crypto/proof_verifier.h" | 13 #include "net/quic/crypto/proof_verifier.h" |
14 #include "net/quic/crypto/proof_verifier_chromium.h" | 14 #include "net/quic/crypto/proof_verifier_chromium.h" |
15 #include "net/quic/crypto/quic_server_info.h" | 15 #include "net/quic/crypto/quic_server_info.h" |
16 #include "net/quic/crypto/quic_server_info.h" | |
ramant (doing other things)
2014/03/12 00:50:56
nit: line 16 could be deleted.
Ryan Hamilton
2014/03/12 04:00:45
Done.
| |
16 #include "net/quic/quic_protocol.h" | 17 #include "net/quic/quic_protocol.h" |
17 #include "net/quic/quic_session.h" | 18 #include "net/quic/quic_session.h" |
18 #include "net/ssl/ssl_connection_status_flags.h" | 19 #include "net/ssl/ssl_connection_status_flags.h" |
19 #include "net/ssl/ssl_info.h" | 20 #include "net/ssl/ssl_info.h" |
20 | 21 |
21 namespace net { | 22 namespace net { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 // Copies CertVerifyResult from |verify_details| to |cert_verify_result|. | 26 // Copies CertVerifyResult from |verify_details| to |cert_verify_result|. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 stream_->DoHandshakeLoop(NULL); | 59 stream_->DoHandshakeLoop(NULL); |
59 | 60 |
60 // The ProofVerifier owns this object and will delete it when this method | 61 // The ProofVerifier owns this object and will delete it when this method |
61 // returns. | 62 // returns. |
62 } | 63 } |
63 | 64 |
64 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { | 65 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { |
65 stream_ = NULL; | 66 stream_ = NULL; |
66 } | 67 } |
67 | 68 |
68 | |
69 QuicCryptoClientStream::QuicCryptoClientStream( | 69 QuicCryptoClientStream::QuicCryptoClientStream( |
70 const string& server_hostname, | 70 const string& server_hostname, |
71 QuicSession* session, | 71 QuicSession* session, |
72 QuicCryptoClientConfig* crypto_config) | 72 QuicCryptoClientConfig* crypto_config) |
73 : QuicCryptoStream(session), | 73 : QuicCryptoStream(session), |
74 next_state_(STATE_IDLE), | 74 next_state_(STATE_IDLE), |
75 num_client_hellos_(0), | 75 num_client_hellos_(0), |
76 crypto_config_(crypto_config), | 76 crypto_config_(crypto_config), |
77 server_hostname_(server_hostname), | 77 server_hostname_(server_hostname), |
78 generation_counter_(0), | 78 generation_counter_(0), |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 *in, session()->connection()->clock()->WallNow(), cached, | 270 *in, session()->connection()->clock()->WallNow(), cached, |
271 &crypto_negotiated_params_, &error_details); | 271 &crypto_negotiated_params_, &error_details); |
272 if (error != QUIC_NO_ERROR) { | 272 if (error != QUIC_NO_ERROR) { |
273 CloseConnectionWithDetails(error, error_details); | 273 CloseConnectionWithDetails(error, error_details); |
274 return; | 274 return; |
275 } | 275 } |
276 if (!cached->proof_valid()) { | 276 if (!cached->proof_valid()) { |
277 ProofVerifier* verifier = crypto_config_->proof_verifier(); | 277 ProofVerifier* verifier = crypto_config_->proof_verifier(); |
278 if (!verifier) { | 278 if (!verifier) { |
279 // If no verifier is set then we don't check the certificates. | 279 // If no verifier is set then we don't check the certificates. |
280 cached->SetProofValid(); | 280 cached->SetProofValid(); |
ramant (doing other things)
2014/03/12 00:50:56
nit: consider calling SaveQuicServerInfo from here
Ryan Hamilton
2014/03/12 04:00:45
Done, and in the other places. We should probably
| |
281 } else if (!cached->signature().empty()) { | 281 } else if (!cached->signature().empty()) { |
282 next_state_ = STATE_VERIFY_PROOF; | 282 next_state_ = STATE_VERIFY_PROOF; |
283 break; | 283 break; |
284 } | 284 } |
285 } | 285 } |
286 next_state_ = STATE_SEND_CHLO; | 286 next_state_ = STATE_SEND_CHLO; |
287 break; | 287 break; |
288 case STATE_VERIFY_PROOF: { | 288 case STATE_VERIFY_PROOF: { |
289 ProofVerifier* verifier = crypto_config_->proof_verifier(); | 289 ProofVerifier* verifier = crypto_config_->proof_verifier(); |
290 DCHECK(verifier); | 290 DCHECK(verifier); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 } | 408 } |
409 } | 409 } |
410 | 410 |
411 void QuicCryptoClientStream::OnIOComplete(int result) { | 411 void QuicCryptoClientStream::OnIOComplete(int result) { |
412 DCHECK_EQ(STATE_LOAD_QUIC_SERVER_INFO_COMPLETE, next_state_); | 412 DCHECK_EQ(STATE_LOAD_QUIC_SERVER_INFO_COMPLETE, next_state_); |
413 DCHECK_NE(ERR_IO_PENDING, result); | 413 DCHECK_NE(ERR_IO_PENDING, result); |
414 disk_cache_load_result_ = result; | 414 disk_cache_load_result_ = result; |
415 DoHandshakeLoop(NULL); | 415 DoHandshakeLoop(NULL); |
416 } | 416 } |
417 | 417 |
418 void QuicCryptoClientStream::SetQuicServerInfo( | |
419 scoped_ptr<QuicServerInfo> server_info) { | |
420 quic_server_info_.reset(server_info.release()); | |
421 } | |
422 | |
418 int QuicCryptoClientStream::DoLoadQuicServerInfo( | 423 int QuicCryptoClientStream::DoLoadQuicServerInfo( |
419 QuicCryptoClientConfig::CachedState* cached) { | 424 QuicCryptoClientConfig::CachedState* cached) { |
420 next_state_ = STATE_SEND_CHLO; | 425 next_state_ = STATE_SEND_CHLO; |
421 QuicServerInfo* quic_server_info = cached->quic_server_info(); | 426 if (!quic_server_info_) { |
422 if (!quic_server_info) { | |
423 return OK; | 427 return OK; |
424 } | 428 } |
425 | 429 |
426 read_start_time_ = base::TimeTicks::Now(); | 430 read_start_time_ = base::TimeTicks::Now(); |
427 generation_counter_ = cached->generation_counter(); | 431 generation_counter_ = cached->generation_counter(); |
428 next_state_ = STATE_LOAD_QUIC_SERVER_INFO_COMPLETE; | 432 next_state_ = STATE_LOAD_QUIC_SERVER_INFO_COMPLETE; |
429 | 433 |
430 // TODO(rtenneti): Use host:port to access QUIC server information from disk | 434 // TODO(rtenneti): Use host:port to access QUIC server information from disk |
431 // cache. If multiple tabs load URLs with same hostname but different | 435 // cache. If multiple tabs load URLs with same hostname but different |
432 // ports, all requests except for the first request send InchoateClientHello. | 436 // ports, all requests except for the first request send InchoateClientHello. |
433 // Fix the code to handle multiple requests. A possible solution is to wait | 437 // Fix the code to handle multiple requests. A possible solution is to wait |
434 // for the first request to finish and use the data from the disk cache for | 438 // for the first request to finish and use the data from the disk cache for |
435 // all requests. | 439 // all requests. |
436 // We may need to call quic_server_info->Persist later. | 440 // We may need to call quic_server_info->Persist later. |
437 // quic_server_info->Persist requires quic_server_info to be ready, so we | 441 // quic_server_info->Persist requires quic_server_info to be ready, so we |
438 // always call WaitForDataReady, even though we might have initialized | 442 // always call WaitForDataReady, even though we might have initialized |
439 // |cached| config from the cached state for a canonical hostname. | 443 // |cached| config from the cached state for a canonical hostname. |
440 int rv = quic_server_info->WaitForDataReady( | 444 int rv = quic_server_info_->WaitForDataReady( |
441 base::Bind(&QuicCryptoClientStream::OnIOComplete, | 445 base::Bind(&QuicCryptoClientStream::OnIOComplete, |
442 weak_factory_.GetWeakPtr())); | 446 weak_factory_.GetWeakPtr())); |
443 | 447 |
444 if (rv != ERR_IO_PENDING) { | 448 if (rv != ERR_IO_PENDING) { |
445 disk_cache_load_result_ = rv; | 449 disk_cache_load_result_ = rv; |
446 } | 450 } |
447 return rv; | 451 return rv; |
448 } | 452 } |
449 | 453 |
450 void QuicCryptoClientStream::DoLoadQuicServerInfoComplete( | 454 void QuicCryptoClientStream::DoLoadQuicServerInfoComplete( |
451 QuicCryptoClientConfig::CachedState* cached) { | 455 QuicCryptoClientConfig::CachedState* cached) { |
452 LoadQuicServerInfo(cached); | 456 LoadQuicServerInfo(cached); |
453 QuicServerInfo::State* state = cached->quic_server_info()->mutable_state(); | 457 QuicServerInfo::State* state = quic_server_info_->mutable_state(); |
454 state->Clear(); | 458 state->Clear(); |
455 } | 459 } |
456 | 460 |
457 void QuicCryptoClientStream::LoadQuicServerInfo( | 461 void QuicCryptoClientStream::LoadQuicServerInfo( |
458 QuicCryptoClientConfig::CachedState* cached) { | 462 QuicCryptoClientConfig::CachedState* cached) { |
459 next_state_ = STATE_SEND_CHLO; | 463 next_state_ = STATE_SEND_CHLO; |
460 | 464 |
461 // If someone else already saved a server config, we don't want to overwrite | 465 // If someone else already saved a server config, we don't want to overwrite |
462 // it. Also, if someone else saved a server config and then cleared it (so | 466 // it. Also, if someone else saved a server config and then cleared it (so |
463 // cached->IsEmpty() is true), we still want to load from QuicServerInfo. | 467 // cached->IsEmpty() is true), we still want to load from QuicServerInfo. |
464 if (!cached->IsEmpty()) { | 468 if (!cached->IsEmpty()) { |
465 return; | 469 return; |
466 } | 470 } |
467 | 471 |
468 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheReadTime", | 472 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheReadTime", |
469 base::TimeTicks::Now() - read_start_time_); | 473 base::TimeTicks::Now() - read_start_time_); |
470 | 474 |
471 if (disk_cache_load_result_ != OK || !cached->LoadQuicServerInfo( | 475 if (disk_cache_load_result_ != OK || |
472 session()->connection()->clock()->WallNow())) { | 476 !cached->Initialize(quic_server_info_->state().server_config, |
477 quic_server_info_->state().server_config_sig, | |
478 quic_server_info_->state().source_address_token, | |
479 quic_server_info_->state().certs, | |
480 session()->connection()->clock()->WallNow())) { | |
473 // It is ok to proceed to STATE_SEND_CHLO when we cannot load QuicServerInfo | 481 // It is ok to proceed to STATE_SEND_CHLO when we cannot load QuicServerInfo |
474 // from the disk cache. | 482 // from the disk cache. |
475 DCHECK(cached->IsEmpty()); | 483 DCHECK(cached->IsEmpty()); |
476 DVLOG(1) << "Empty server_config"; | 484 DVLOG(1) << "Empty server_config"; |
477 return; | 485 return; |
478 } | 486 } |
479 | 487 |
480 ProofVerifier* verifier = crypto_config_->proof_verifier(); | 488 ProofVerifier* verifier = crypto_config_->proof_verifier(); |
481 if (!verifier) { | 489 if (!verifier) { |
482 // If no verifier is set then we don't check the certificates. | 490 // If no verifier is set then we don't check the certificates. |
483 cached->SetProofValid(); | 491 cached->SetProofValid(); |
484 } else if (!cached->signature().empty()) { | 492 } else if (!cached->signature().empty()) { |
485 next_state_ = STATE_VERIFY_PROOF; | 493 next_state_ = STATE_VERIFY_PROOF; |
486 } | 494 } |
487 } | 495 } |
488 | 496 |
497 void QuicCryptoClientStream::SaveQuicServerInfo( | |
498 QuicCryptoClientConfig::CachedState* cached) { | |
499 DCHECK(cached->proof_valid()); | |
500 | |
501 // If the QuicServerInfo hasn't managed to load from disk yet then we can't | |
502 // save anything. TODO(rtenneti): we should fix this. | |
503 if (!quic_server_info_->IsDataReady()) { | |
504 return; | |
505 } | |
506 | |
507 QuicServerInfo::State* state = quic_server_info_->mutable_state(); | |
508 | |
509 state->server_config = cached->server_config(); | |
510 state->source_address_token = cached->source_address_token(); | |
511 state->server_config_sig = cached->signature(); | |
512 state->certs = cached->certs(); | |
513 | |
514 quic_server_info_->Persist(); | |
515 } | |
516 | |
489 } // namespace net | 517 } // namespace net |
OLD | NEW |