summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-14 10:08:04 +0000
committerrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-14 10:08:04 +0000
commit17bf15c9ea5ee0c9676f88d56fe1a2d6722c311a (patch)
tree91d218d5b309a6a1fce8cd4fbc0cf6db510e905e
parent93506aea4b6764d11f70457c735cb5e5ec083283 (diff)
downloadchromium_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.h2
-rw-r--r--net/quic/crypto/quic_crypto_client_config.cc115
-rw-r--r--net/quic/crypto/quic_crypto_client_config.h37
-rw-r--r--net/quic/quic_client_session.cc4
-rw-r--r--net/quic/quic_client_session.h1
-rw-r--r--net/quic/quic_client_session_test.cc4
-rw-r--r--net/quic/quic_crypto_client_stream.cc44
-rw-r--r--net/quic/quic_crypto_client_stream.h10
-rw-r--r--net/quic/quic_http_stream_test.cc2
-rw-r--r--net/quic/quic_stream_factory.cc66
-rw-r--r--net/quic/quic_stream_factory.h1
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);