diff options
author | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-14 10:08:04 +0000 |
---|---|---|
committer | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-14 10:08:04 +0000 |
commit | 17bf15c9ea5ee0c9676f88d56fe1a2d6722c311a (patch) | |
tree | 91d218d5b309a6a1fce8cd4fbc0cf6db510e905e | |
parent | 93506aea4b6764d11f70457c735cb5e5ec083283 (diff) | |
download | chromium_src-17bf15c9ea5ee0c9676f88d56fe1a2d6722c311a.zip chromium_src-17bf15c9ea5ee0c9676f88d56fe1a2d6722c311a.tar.gz chromium_src-17bf15c9ea5ee0c9676f88d56fe1a2d6722c311a.tar.bz2 |
Move QuicServerInfo management from CachedState to the QuicStreamFactory
and QuicCryptoClientStream.
Review URL: https://codereview.chromium.org/196403002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@257063 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/quic/crypto/proof_verifier.h | 2 | ||||
-rw-r--r-- | net/quic/crypto/quic_crypto_client_config.cc | 115 | ||||
-rw-r--r-- | net/quic/crypto/quic_crypto_client_config.h | 37 | ||||
-rw-r--r-- | net/quic/quic_client_session.cc | 4 | ||||
-rw-r--r-- | net/quic/quic_client_session.h | 1 | ||||
-rw-r--r-- | net/quic/quic_client_session_test.cc | 4 | ||||
-rw-r--r-- | net/quic/quic_crypto_client_stream.cc | 44 | ||||
-rw-r--r-- | net/quic/quic_crypto_client_stream.h | 10 | ||||
-rw-r--r-- | net/quic/quic_http_stream_test.cc | 2 | ||||
-rw-r--r-- | net/quic/quic_stream_factory.cc | 66 | ||||
-rw-r--r-- | net/quic/quic_stream_factory.h | 1 |
11 files changed, 147 insertions, 139 deletions
diff --git a/net/quic/crypto/proof_verifier.h b/net/quic/crypto/proof_verifier.h index a2ef8f2..b576ca5 100644 --- a/net/quic/crypto/proof_verifier.h +++ b/net/quic/crypto/proof_verifier.h @@ -15,7 +15,7 @@ namespace net { // ProofVerifyDetails is an abstract class that acts as a container for any // implementation specific details that a ProofVerifier wishes to return. These -// details are saved in the CachedInfo for the origin in question. +// details are saved in the CachedState for the origin in question. class NET_EXPORT_PRIVATE ProofVerifyDetails { public: virtual ~ProofVerifyDetails() {} diff --git a/net/quic/crypto/quic_crypto_client_config.cc b/net/quic/crypto/quic_crypto_client_config.cc index 5ee46b2..3b075868 100644 --- a/net/quic/crypto/quic_crypto_client_config.cc +++ b/net/quic/crypto/quic_crypto_client_config.cc @@ -15,7 +15,6 @@ #include "net/quic/crypto/p256_key_exchange.h" #include "net/quic/crypto/proof_verifier.h" #include "net/quic/crypto/quic_encrypter.h" -#include "net/quic/crypto/quic_server_info.h" #include "net/quic/quic_utils.h" #if defined(OS_WIN) @@ -37,16 +36,8 @@ QuicCryptoClientConfig::~QuicCryptoClientConfig() { QuicCryptoClientConfig::CachedState::CachedState() : server_config_valid_(false), - need_to_persist_(false), generation_counter_(0) {} -QuicCryptoClientConfig::CachedState::CachedState( - scoped_ptr<QuicServerInfo> quic_server_info) - : server_config_valid_(false), - need_to_persist_(false), - generation_counter_(0), - quic_server_info_(quic_server_info.Pass()) {} - QuicCryptoClientConfig::CachedState::~CachedState() {} bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { @@ -123,7 +114,6 @@ QuicErrorCode QuicCryptoClientConfig::CachedState::SetServerConfig( server_config_ = server_config.as_string(); SetProofInvalid(); scfg_.reset(new_scfg_storage.release()); - need_to_persist_ = true; } return QUIC_NO_ERROR; } @@ -166,7 +156,6 @@ void QuicCryptoClientConfig::CachedState::ClearProof() { void QuicCryptoClientConfig::CachedState::SetProofValid() { server_config_valid_ = true; - SaveQuicServerInfo(); } void QuicCryptoClientConfig::CachedState::SetProofInvalid() { @@ -174,6 +163,32 @@ void QuicCryptoClientConfig::CachedState::SetProofInvalid() { ++generation_counter_; } +bool QuicCryptoClientConfig::CachedState::Initialize( + StringPiece server_config, + StringPiece source_address_token, + const vector<string>& certs, + StringPiece signature, + QuicWallTime now) { + DCHECK(server_config_.empty()); + + if (server_config.empty()) { + return false; + } + + string error_details; + QuicErrorCode error = SetServerConfig(server_config, now, + &error_details); + if (error != QUIC_NO_ERROR) { + DVLOG(1) << "SetServerConfig failed with " << error_details; + return false; + } + + signature.CopyToString(&server_config_sig_); + source_address_token.CopyToString(&source_address_token_); + certs_ = certs; + return true; +} + const string& QuicCryptoClientConfig::CachedState::server_config() const { return server_config_; } @@ -204,10 +219,6 @@ QuicCryptoClientConfig::CachedState::proof_verify_details() const { return proof_verify_details_.get(); } -QuicServerInfo* QuicCryptoClientConfig::CachedState::quic_server_info() const { - return quic_server_info_.get(); -} - void QuicCryptoClientConfig::CachedState::set_source_address_token( StringPiece token) { source_address_token_ = token.as_string(); @@ -230,59 +241,6 @@ void QuicCryptoClientConfig::CachedState::InitializeFrom( ++generation_counter_; } -// An issue to be solved: while we are loading the data from disk cache, it is -// possible for another request for the same hostname update the CachedState -// because that request has sent FillInchoateClientHello and got REJ message. -// Loading of data from disk cache shouldn't blindly overwrite what is in -// CachedState. -bool QuicCryptoClientConfig::CachedState::LoadQuicServerInfo(QuicWallTime now) { - DCHECK(server_config_.empty()); - DCHECK(quic_server_info_.get()); - DCHECK(quic_server_info_->IsDataReady()); - - const QuicServerInfo::State& state(quic_server_info_->state()); - if (state.server_config.empty()) { - return false; - } - - string error_details; - QuicErrorCode error = SetServerConfig(state.server_config, now, - &error_details); - if (error != QUIC_NO_ERROR) { - DVLOG(1) << "SetServerConfig failed with " << error_details; - return false; - } - - source_address_token_ = state.source_address_token; - server_config_sig_ = state.server_config_sig; - certs_ = state.certs; - need_to_persist_ = false; - return true; -} - -void QuicCryptoClientConfig::CachedState::SaveQuicServerInfo() { - if (!quic_server_info_.get() || !need_to_persist_) { - return; - } - DCHECK(server_config_valid_); - - // If the QuicServerInfo hasn't managed to load from disk yet then we can't - // save anything. TODO(rtenneti): we should fix this. - if (!quic_server_info_->IsDataReady()) { - return; - } - - QuicServerInfo::State* state = quic_server_info_->mutable_state(); - - state->server_config = server_config_; - state->source_address_token = source_address_token_; - state->server_config_sig = server_config_sig_; - state->certs = certs_; - - quic_server_info_->Persist(); - need_to_persist_ = false; -} - void QuicCryptoClientConfig::SetDefaults() { // Key exchange methods. kexs.resize(2); @@ -294,22 +252,6 @@ void QuicCryptoClientConfig::SetDefaults() { aead[0] = kAESG; } -QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::Create( - const string& server_hostname, - QuicServerInfoFactory* quic_server_info_factory) { - DCHECK(cached_states_.find(server_hostname) == cached_states_.end()); - scoped_ptr<QuicServerInfo> quic_server_info; - if (quic_server_info_factory) { - quic_server_info.reset( - quic_server_info_factory->GetForHost(server_hostname)); - quic_server_info->Start(); - } - - CachedState* cached = new CachedState(quic_server_info.Pass()); - cached_states_.insert(make_pair(server_hostname, cached)); - return cached; -} - QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( const string& server_hostname) { map<string, CachedState*>::const_iterator it = @@ -317,7 +259,10 @@ QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( if (it != cached_states_.end()) { return it->second; } - return Create(server_hostname, NULL); + + CachedState* cached = new CachedState; + cached_states_.insert(make_pair(server_hostname, cached)); + return cached; } void QuicCryptoClientConfig::FillInchoateClientHello( diff --git a/net/quic/crypto/quic_crypto_client_config.h b/net/quic/crypto/quic_crypto_client_config.h index 896f5fb..f29157c 100644 --- a/net/quic/crypto/quic_crypto_client_config.h +++ b/net/quic/crypto/quic_crypto_client_config.h @@ -22,8 +22,6 @@ class CryptoHandshakeMessage; class ProofVerifier; class ProofVerifyDetails; class QuicRandom; -class QuicServerInfo; -class QuicServerInfoFactory; // QuicCryptoClientConfig contains crypto-related configuration settings for a // client. Note that this object isn't thread-safe. It's designed to be used on @@ -36,7 +34,6 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { class NET_EXPORT_PRIVATE CachedState { public: CachedState(); - explicit CachedState(scoped_ptr<QuicServerInfo> quic_server_info); ~CachedState(); // IsComplete returns true if this object contains enough information to @@ -70,8 +67,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { void ClearProof(); // SetProofValid records that the certificate chain and signature have been - // validated and that it's safe to assume that the server is legitimate. It - // persists the server config information to disk cache. + // validated and that it's safe to assume that the server is legitimate. // (Note: this does not check the chain or signature.) void SetProofValid(); @@ -87,7 +83,6 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { bool proof_valid() const; uint64 generation_counter() const; const ProofVerifyDetails* proof_verify_details() const; - QuicServerInfo* quic_server_info() const; void set_source_address_token(base::StringPiece token); @@ -100,16 +95,13 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // unchanged. void InitializeFrom(const CachedState& other); - // Fill out the |server_config_|, |source_address_token_|, |certs_| and - // |server_config_sig_| fields from |quic_server_info_|. |quic_server_info_| - // reads this information from the disk cache. |now| is used to judge - // whether server config from disk cache has expired. Returns true if it has - // loaded the data from disk cache successfully. - bool LoadQuicServerInfo(QuicWallTime now); - - // Save the server config information so that we can perform 0-RTT handshake - // with a server. - void SaveQuicServerInfo(); + // Initializes this cached state based on the arguments provided. + // Returns false if there is a problem parsing the server config. + bool Initialize(base::StringPiece server_config, + base::StringPiece source_address_token, + const std::vector<std::string>& certs, + base::StringPiece signature, + QuicWallTime now); private: std::string server_config_; // A serialized handshake message. @@ -120,7 +112,6 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { bool server_config_valid_; // True if |server_config_| is correctly // signed and |certs_| has been // validated. - bool need_to_persist_; // Persist to disk if True. // Generation counter associated with the |server_config_|, |certs_| and // |server_config_sig_| combination. It is incremented whenever we set // server_config_valid_ to false. @@ -131,9 +122,6 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // scfg contains the cached, parsed value of |server_config|. mutable scoped_ptr<CryptoHandshakeMessage> scfg_; - // |quic_server_info_| is used to fetch crypto config information from disk. - scoped_ptr<QuicServerInfo> quic_server_info_; - DISALLOW_COPY_AND_ASSIGN(CachedState); }; @@ -143,17 +131,8 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // Sets the members to reasonable, default values. void SetDefaults(); - // Create returns a CachedState for the given hostname. It creates a - // CachedState and caches it. If |quic_server_info_factory| is not NULL, then - // it is used to create QuicServerInfo which is used to fetch crypto config - // information from disk for the given hostname. - CachedState* Create(const std::string& server_hostname, - QuicServerInfoFactory* quic_server_info_factory); - // LookupOrCreate returns a CachedState for the given hostname. If no such // CachedState currently exists, it will be created and cached. - // TODO(rtenneti): fix the server code and pass QuicServerInfoFactory as - // argument. CachedState* LookupOrCreate(const std::string& server_hostname); // FillInchoateClientHello sets |out| to be a CHLO message that elicits a diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc index 3ec2c89..a65324e 100644 --- a/net/quic/quic_client_session.cc +++ b/net/quic/quic_client_session.cc @@ -13,6 +13,7 @@ #include "base/values.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" +#include "net/quic/crypto/quic_server_info.h" #include "net/quic/quic_connection_helper.h" #include "net/quic/quic_crypto_client_stream_factory.h" #include "net/quic/quic_default_packet_writer.h" @@ -85,6 +86,7 @@ QuicClientSession::QuicClientSession( scoped_ptr<DatagramClientSocket> socket, scoped_ptr<QuicDefaultPacketWriter> writer, QuicStreamFactory* stream_factory, + scoped_ptr<QuicServerInfo> server_info, QuicCryptoClientStreamFactory* crypto_client_stream_factory, const string& server_hostname, const QuicConfig& config, @@ -108,6 +110,8 @@ QuicClientSession::QuicClientSession( server_hostname, this, crypto_config) : new QuicCryptoClientStream(server_hostname, this, crypto_config)); + crypto_stream_->SetQuicServerInfo(server_info.Pass()); + connection->set_debug_visitor(&logger_); // TODO(rch): pass in full host port proxy pair net_log_.BeginEvent( diff --git a/net/quic/quic_client_session.h b/net/quic/quic_client_session.h index 204d397..f56a9b6 100644 --- a/net/quic/quic_client_session.h +++ b/net/quic/quic_client_session.h @@ -90,6 +90,7 @@ class NET_EXPORT_PRIVATE QuicClientSession : public QuicSession { scoped_ptr<DatagramClientSocket> socket, scoped_ptr<QuicDefaultPacketWriter> writer, QuicStreamFactory* stream_factory, + scoped_ptr<QuicServerInfo> server_info, QuicCryptoClientStreamFactory* crypto_client_stream_factory, const std::string& server_hostname, const QuicConfig& config, diff --git a/net/quic/quic_client_session_test.cc b/net/quic/quic_client_session_test.cc index 5e0ea53..ba8ba97 100644 --- a/net/quic/quic_client_session_test.cc +++ b/net/quic/quic_client_session_test.cc @@ -13,6 +13,7 @@ #include "net/quic/crypto/crypto_protocol.h" #include "net/quic/crypto/quic_decrypter.h" #include "net/quic/crypto/quic_encrypter.h" +#include "net/quic/crypto/quic_server_info.h" #include "net/quic/quic_default_packet_writer.h" #include "net/quic/test_tools/crypto_test_utils.h" #include "net/quic/test_tools/quic_client_session_peer.h" @@ -66,7 +67,8 @@ class QuicClientSessionTest : public ::testing::TestWithParam<QuicVersion> { : writer_(new TestPacketWriter()), connection_( new PacketSavingConnection(false, SupportedVersions(GetParam()))), - session_(connection_, GetSocket().Pass(), writer_.Pass(), NULL, NULL, + session_(connection_, GetSocket().Pass(), writer_.Pass(), NULL, + make_scoped_ptr((QuicServerInfo*)NULL), NULL, kServerHostname, DefaultQuicConfig(), &crypto_config_, &net_log_) { session_.config()->SetDefaults(); diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc index ab32cf0f..5afa482 100644 --- a/net/quic/quic_crypto_client_stream.cc +++ b/net/quic/quic_crypto_client_stream.cc @@ -65,7 +65,6 @@ void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { stream_ = NULL; } - QuicCryptoClientStream::QuicCryptoClientStream( const string& server_hostname, QuicSession* session, @@ -278,6 +277,7 @@ void QuicCryptoClientStream::DoHandshakeLoop( if (!verifier) { // If no verifier is set then we don't check the certificates. cached->SetProofValid(); + SaveQuicServerInfo(*cached); } else if (!cached->signature().empty()) { next_state_ = STATE_VERIFY_PROOF; break; @@ -332,6 +332,7 @@ void QuicCryptoClientStream::DoHandshakeLoop( } else { cached->SetProofValid(); cached->SetProofVerifyDetails(verify_details_.release()); + SaveQuicServerInfo(*cached); next_state_ = STATE_SEND_CHLO; } break; @@ -415,11 +416,15 @@ void QuicCryptoClientStream::OnIOComplete(int result) { DoHandshakeLoop(NULL); } +void QuicCryptoClientStream::SetQuicServerInfo( + scoped_ptr<QuicServerInfo> server_info) { + quic_server_info_.reset(server_info.release()); +} + int QuicCryptoClientStream::DoLoadQuicServerInfo( QuicCryptoClientConfig::CachedState* cached) { next_state_ = STATE_SEND_CHLO; - QuicServerInfo* quic_server_info = cached->quic_server_info(); - if (!quic_server_info) { + if (!quic_server_info_) { return OK; } @@ -437,7 +442,7 @@ int QuicCryptoClientStream::DoLoadQuicServerInfo( // quic_server_info->Persist requires quic_server_info to be ready, so we // always call WaitForDataReady, even though we might have initialized // |cached| config from the cached state for a canonical hostname. - int rv = quic_server_info->WaitForDataReady( + int rv = quic_server_info_->WaitForDataReady( base::Bind(&QuicCryptoClientStream::OnIOComplete, weak_factory_.GetWeakPtr())); @@ -450,7 +455,7 @@ int QuicCryptoClientStream::DoLoadQuicServerInfo( void QuicCryptoClientStream::DoLoadQuicServerInfoComplete( QuicCryptoClientConfig::CachedState* cached) { LoadQuicServerInfo(cached); - QuicServerInfo::State* state = cached->quic_server_info()->mutable_state(); + QuicServerInfo::State* state = quic_server_info_->mutable_state(); state->Clear(); } @@ -468,8 +473,12 @@ void QuicCryptoClientStream::LoadQuicServerInfo( UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheReadTime", base::TimeTicks::Now() - disk_cache_load_start_time_); - if (disk_cache_load_result_ != OK || !cached->LoadQuicServerInfo( - session()->connection()->clock()->WallNow())) { + if (disk_cache_load_result_ != OK || + !cached->Initialize(quic_server_info_->state().server_config, + quic_server_info_->state().source_address_token, + quic_server_info_->state().certs, + quic_server_info_->state().server_config_sig, + session()->connection()->clock()->WallNow())) { // It is ok to proceed to STATE_SEND_CHLO when we cannot load QuicServerInfo // from the disk cache. DCHECK(cached->IsEmpty()); @@ -481,9 +490,30 @@ void QuicCryptoClientStream::LoadQuicServerInfo( if (!verifier) { // If no verifier is set then we don't check the certificates. cached->SetProofValid(); + SaveQuicServerInfo(*cached); } else if (!cached->signature().empty()) { next_state_ = STATE_VERIFY_PROOF; } } +void QuicCryptoClientStream::SaveQuicServerInfo( + const QuicCryptoClientConfig::CachedState& cached) { + DCHECK(cached.proof_valid()); + + // If the QuicServerInfo hasn't managed to load from disk yet then we can't + // save anything. TODO(rtenneti): we should fix this. + if (!quic_server_info_ || !quic_server_info_->IsDataReady()) { + return; + } + + QuicServerInfo::State* state = quic_server_info_->mutable_state(); + + state->server_config = cached.server_config(); + state->source_address_token = cached.source_address_token(); + state->server_config_sig = cached.signature(); + state->certs = cached.certs(); + + quic_server_info_->Persist(); +} + } // namespace net diff --git a/net/quic/quic_crypto_client_stream.h b/net/quic/quic_crypto_client_stream.h index 12198d9..1f4c98b 100644 --- a/net/quic/quic_crypto_client_stream.h +++ b/net/quic/quic_crypto_client_stream.h @@ -18,7 +18,7 @@ namespace net { -class ProofVerifyDetails; +class QuicServerInfo; class QuicSession; class SSLInfo; @@ -52,6 +52,8 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream { void OnIOComplete(int result); + void SetQuicServerInfo(scoped_ptr<QuicServerInfo> server_info); + private: // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof. // The ProofVerifier calls this class with the result of proof verification @@ -103,6 +105,10 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream { // LoadQuicServerInfo is a helper function for DoLoadQuicServerInfoComplete. void LoadQuicServerInfo(QuicCryptoClientConfig::CachedState* cached); + // Should be aclled whenever cached->SetProofValid() is called. + // TODO(rch): move this to some chrome-specific class. + void SaveQuicServerInfo(const QuicCryptoClientConfig::CachedState& cached); + State next_state_; // num_client_hellos_ contains the number of client hello messages that this // connection has sent. @@ -132,6 +138,8 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream { // The result of certificate verification. scoped_ptr<CertVerifyResult> cert_verify_result_; + scoped_ptr<QuicServerInfo> quic_server_info_; + // This member is used to store the result of an asynchronous disk cache read. // It must not be used after STATE_LOAD_QUIC_SERVER_INFO_COMPLETE. int disk_cache_load_result_; diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc index 7fef0c5..316f114 100644 --- a/net/quic/quic_http_stream_test.cc +++ b/net/quic/quic_http_stream_test.cc @@ -16,6 +16,7 @@ #include "net/quic/crypto/crypto_protocol.h" #include "net/quic/crypto/quic_decrypter.h" #include "net/quic/crypto/quic_encrypter.h" +#include "net/quic/crypto/quic_server_info.h" #include "net/quic/quic_client_session.h" #include "net/quic/quic_connection.h" #include "net/quic/quic_connection_helper.h" @@ -203,6 +204,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { new QuicClientSession(connection_, scoped_ptr<DatagramClientSocket>(socket), writer_.Pass(), NULL, + make_scoped_ptr((QuicServerInfo*)NULL), &crypto_client_stream_factory_, "www.google.com", DefaultQuicConfig(), &crypto_config_, NULL)); diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index cfdbf9e..f1e29c1 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc @@ -77,6 +77,7 @@ class QuicStreamFactory::Job { bool is_https, base::StringPiece method, CertVerifier* cert_verifier, + QuicServerInfo* server_info, const BoundNetLog& net_log); ~Job(); @@ -84,6 +85,8 @@ class QuicStreamFactory::Job { int Run(const CompletionCallback& callback); int DoLoop(int rv); + int DoLoadServerInfo(); + int DoLoadServerInfoComplete(int rv); int DoResolveHost(); int DoResolveHostComplete(int rv); int DoConnect(); @@ -102,6 +105,8 @@ class QuicStreamFactory::Job { private: enum IoState { STATE_NONE, + STATE_LOAD_SERVER_INFO, + STATE_LOAD_SERVER_INFO_COMPLETE, STATE_RESOLVE_HOST, STATE_RESOLVE_HOST_COMPLETE, STATE_CONNECT, @@ -115,6 +120,7 @@ class QuicStreamFactory::Job { QuicSessionKey session_key_; bool is_post_; CertVerifier* cert_verifier_; + scoped_ptr<QuicServerInfo> server_info_; const BoundNetLog net_log_; QuicClientSession* session_; CompletionCallback callback_; @@ -128,6 +134,7 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory, bool is_https, base::StringPiece method, CertVerifier* cert_verifier, + QuicServerInfo* server_info, const BoundNetLog& net_log) : factory_(factory), host_resolver_(host_resolver), @@ -135,6 +142,7 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory, session_key_(host_port_pair, is_https), is_post_(method == "POST"), cert_verifier_(cert_verifier), + server_info_(server_info), net_log_(net_log), session_(NULL) {} @@ -142,7 +150,7 @@ QuicStreamFactory::Job::~Job() { } int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { - io_state_ = STATE_RESOLVE_HOST; + io_state_ = STATE_LOAD_SERVER_INFO; int rv = DoLoop(OK); if (rv == ERR_IO_PENDING) callback_ = callback; @@ -155,6 +163,13 @@ int QuicStreamFactory::Job::DoLoop(int rv) { IoState state = io_state_; io_state_ = STATE_NONE; switch (state) { + case STATE_LOAD_SERVER_INFO: + CHECK_EQ(OK, rv); + rv = DoLoadServerInfo(); + break; + case STATE_LOAD_SERVER_INFO_COMPLETE: + rv = DoLoadServerInfoComplete(rv); + break; case STATE_RESOLVE_HOST: CHECK_EQ(OK, rv); rv = DoResolveHost(); @@ -185,6 +200,23 @@ void QuicStreamFactory::Job::OnIOComplete(int rv) { } } +int QuicStreamFactory::Job::DoLoadServerInfo() { + io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; + + if (server_info_) + server_info_->Start(); + + return OK; +} + +int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { + if (rv != OK) + return rv; + + io_state_ = STATE_RESOLVE_HOST; + return OK; +} + int QuicStreamFactory::Job::DoResolveHost() { io_state_ = STATE_RESOLVE_HOST_COMPLETE; return host_resolver_.Resolve( @@ -263,7 +295,8 @@ int QuicStreamFactory::Job::DoConnect() { io_state_ = STATE_CONNECT_COMPLETE; int rv = factory_->CreateSession(session_key_.host_port_pair(), is_https_, - cert_verifier_, address_list_, net_log_, &session_); + cert_verifier_, server_info_.Pass(), + address_list_, net_log_, &session_); if (rv != OK) { DCHECK(rv != ERR_IO_PENDING); DCHECK(!session_); @@ -361,13 +394,21 @@ int QuicStreamFactory::Create(const HostPortPair& host_port_pair, return ERR_IO_PENDING; } - // Create crypto config and start the process of loading QUIC server - // information from disk cache. - QuicCryptoClientConfig* crypto_config = GetOrCreateCryptoConfig(session_key); - DCHECK(crypto_config); - + QuicServerInfo* quic_server_info = NULL; + if (quic_server_info_factory_) { + QuicCryptoClientConfig* crypto_config = + GetOrCreateCryptoConfig(session_key); + QuicCryptoClientConfig::CachedState* cached = + crypto_config->LookupOrCreate(session_key.host_port_pair().host()); + DCHECK(cached); + if (cached->IsEmpty()) { + quic_server_info = + quic_server_info_factory_->GetForHost(host_port_pair.host()); + } + } scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, - is_https, method, cert_verifier, net_log)); + is_https, method, cert_verifier, + quic_server_info, net_log)); int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, base::Unretained(this), job.get())); @@ -593,6 +634,7 @@ int QuicStreamFactory::CreateSession( const HostPortPair& host_port_pair, bool is_https, CertVerifier* cert_verifier, + scoped_ptr<QuicServerInfo> server_info, const AddressList& address_list, const BoundNetLog& net_log, QuicClientSession** session) { @@ -672,7 +714,7 @@ int QuicStreamFactory::CreateSession( } *session = new QuicClientSession( - connection, socket.Pass(), writer.Pass(), this, + connection, socket.Pass(), writer.Pass(), this, server_info.Pass(), quic_crypto_client_stream_factory_, host_port_pair.host(), config, crypto_config, net_log.net_log()); all_sessions_.insert(*session); // owning pointer @@ -710,12 +752,6 @@ QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig( // TODO(rtenneti): if two quic_sessions for the same host_port_pair // share the same crypto_config, will it cause issues? crypto_config = new QuicCryptoClientConfig(); - if (quic_server_info_factory_) { - QuicCryptoClientConfig::CachedState* cached = - crypto_config->Create(session_key.host_port_pair().host(), - quic_server_info_factory_); - DCHECK(cached); - } crypto_config->SetDefaults(); all_crypto_configs_[session_key] = crypto_config; PopulateFromCanonicalConfig(session_key, crypto_config); diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h index 8d49279..9c0edf4 100644 --- a/net/quic/quic_stream_factory.h +++ b/net/quic/quic_stream_factory.h @@ -206,6 +206,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory int CreateSession(const HostPortPair& host_port_pair, bool is_https, CertVerifier* cert_verifier, + scoped_ptr<QuicServerInfo> quic_server_info, const AddressList& address_list, const BoundNetLog& net_log, QuicClientSession** session); |