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

Unified Diff: net/quic/quic_stream_factory.cc

Issue 190063008: Include the scheme in the key for QUIC the session map. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: net/quic/quic_stream_factory.cc
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index f445cd3e8f7a07579cc0fe7e5cab6cf3fa55ea5f..c92f184e42d187463950df7bfe762855fd9f96a7 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -38,6 +38,57 @@ using std::vector;
namespace net {
+QuicStreamFactory::SessionKey::SessionKey() {}
+
+QuicStreamFactory::SessionKey::SessionKey(
+ HostPortProxyPair host_port_proxy_pair,
+ bool is_https)
+ : host_port_proxy_pair(host_port_proxy_pair),
+ is_https(is_https) {}
+
+QuicStreamFactory::SessionKey::~SessionKey() {}
+
+bool QuicStreamFactory::SessionKey::operator<(
+ const QuicStreamFactory::SessionKey &other) const {
+ if (!host_port_proxy_pair.first.Equals(other.host_port_proxy_pair.first)) {
+ return host_port_proxy_pair.first < other.host_port_proxy_pair.first;
+ }
+ if (!(host_port_proxy_pair.second == other.host_port_proxy_pair.second)) {
+ return host_port_proxy_pair.second < other.host_port_proxy_pair.second;
+ }
+ return is_https < other.is_https;
+}
+
+bool QuicStreamFactory::SessionKey::operator==(
+ const QuicStreamFactory::SessionKey& other) const {
+ return is_https == other.is_https &&
+ host_port_proxy_pair.second == other.host_port_proxy_pair.second &&
+ host_port_proxy_pair.first.Equals(other.host_port_proxy_pair.first);
+};
+
+QuicStreamFactory::IpAliasKey::IpAliasKey() {}
+
+QuicStreamFactory::IpAliasKey::IpAliasKey(IPEndPoint ip_endpoint,
+ bool is_https)
+ : ip_endpoint(ip_endpoint),
+ is_https(is_https) {}
+
+QuicStreamFactory::IpAliasKey::~IpAliasKey() {}
+
+bool QuicStreamFactory::IpAliasKey::operator<(
+ const QuicStreamFactory::IpAliasKey& other) const {
+ if (!(ip_endpoint == other.ip_endpoint)) {
+ return ip_endpoint < other.ip_endpoint;
+ }
+ return is_https < other.is_https;
+}
+
+bool QuicStreamFactory::IpAliasKey::operator==(
+ const QuicStreamFactory::IpAliasKey& other) const {
+ return is_https == other.is_https &&
+ ip_endpoint == other.ip_endpoint;
+};
+
// Responsible for creating a new QUIC session to the specified server, and
// for notifying any associated requests when complete.
class QuicStreamFactory::Job {
@@ -66,8 +117,8 @@ class QuicStreamFactory::Job {
return callback_;
}
- const HostPortProxyPair& host_port_proxy_pair() const {
- return host_port_proxy_pair_;
+ const SessionKey session_key() const {
+ return session_key_;
}
private:
@@ -82,8 +133,8 @@ class QuicStreamFactory::Job {
QuicStreamFactory* factory_;
SingleRequestHostResolver host_resolver_;
- const HostPortProxyPair host_port_proxy_pair_;
bool is_https_;
+ SessionKey session_key_;
bool is_post_;
CertVerifier* cert_verifier_;
const BoundNetLog net_log_;
@@ -102,8 +153,8 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory,
const BoundNetLog& net_log)
: factory_(factory),
host_resolver_(host_resolver),
- host_port_proxy_pair_(host_port_proxy_pair),
is_https_(is_https),
+ session_key_(host_port_proxy_pair, is_https),
is_post_(method == "POST"),
cert_verifier_(cert_verifier),
net_log_(net_log),
@@ -159,7 +210,7 @@ void QuicStreamFactory::Job::OnIOComplete(int rv) {
int QuicStreamFactory::Job::DoResolveHost() {
io_state_ = STATE_RESOLVE_HOST_COMPLETE;
return host_resolver_.Resolve(
- HostResolver::RequestInfo(host_port_proxy_pair_.first),
+ HostResolver::RequestInfo(session_key_.host_port_proxy_pair.first),
DEFAULT_PRIORITY,
&address_list_,
base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)),
@@ -170,11 +221,11 @@ int QuicStreamFactory::Job::DoResolveHostComplete(int rv) {
if (rv != OK)
return rv;
- DCHECK(!factory_->HasActiveSession(host_port_proxy_pair_));
+ DCHECK(!factory_->HasActiveSession(session_key_));
// Inform the factory of this resolution, which will set up
// a session alias, if possible.
- if (factory_->OnResolution(host_port_proxy_pair_, address_list_)) {
+ if (factory_->OnResolution(session_key_, address_list_)) {
return OK;
}
@@ -199,8 +250,8 @@ int QuicStreamRequest::Request(const HostPortProxyPair& host_port_proxy_pair,
DCHECK(!stream_);
DCHECK(callback_.is_null());
DCHECK(factory_);
- int rv = factory_->Create(
- host_port_proxy_pair, is_https, method, cert_verifier, net_log, this);
+ int rv = factory_->Create(host_port_proxy_pair, is_https,
+ method, cert_verifier, net_log, this);
if (rv == ERR_IO_PENDING) {
host_port_proxy_pair_ = host_port_proxy_pair;
is_https_ = is_https;
@@ -233,7 +284,7 @@ scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() {
int QuicStreamFactory::Job::DoConnect() {
io_state_ = STATE_CONNECT_COMPLETE;
- int rv = factory_->CreateSession(host_port_proxy_pair_, is_https_,
+ int rv = factory_->CreateSession(session_key_.host_port_proxy_pair, is_https_,
cert_verifier_, address_list_, net_log_, &session_);
if (rv != OK) {
DCHECK(rv != ERR_IO_PENDING);
@@ -256,17 +307,18 @@ int QuicStreamFactory::Job::DoConnectComplete(int rv) {
if (rv != OK)
return rv;
- DCHECK(!factory_->HasActiveSession(host_port_proxy_pair_));
+ DCHECK(!factory_->HasActiveSession(session_key_));
// There may well now be an active session for this IP. If so, use the
// existing session instead.
AddressList address(session_->connection()->peer_address());
- if (factory_->OnResolution(host_port_proxy_pair_, address)) {
+ if (factory_->OnResolution(session_key_, address)) {
+
session_->connection()->SendConnectionClose(QUIC_NO_ERROR);
session_ = NULL;
return OK;
}
- factory_->ActivateSession(host_port_proxy_pair_, session_);
+ factory_->ActivateSession(session_key_, session_);
return OK;
}
@@ -319,13 +371,14 @@ int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair,
CertVerifier* cert_verifier,
const BoundNetLog& net_log,
QuicStreamRequest* request) {
- if (HasActiveSession(host_port_proxy_pair)) {
- request->set_stream(CreateIfSessionExists(host_port_proxy_pair, net_log));
+ SessionKey key(host_port_proxy_pair, is_https);
+ if (HasActiveSession(key)) {
+ request->set_stream(CreateIfSessionExists(key, net_log));
return OK;
}
- if (HasActiveJob(host_port_proxy_pair)) {
- Job* job = active_jobs_[host_port_proxy_pair];
+ if (HasActiveJob(key)) {
+ Job* job = active_jobs_[key];
active_requests_[request] = job;
job_requests_map_[job].insert(request);
return ERR_IO_PENDING;
@@ -345,32 +398,33 @@ int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair,
if (rv == ERR_IO_PENDING) {
active_requests_[request] = job.get();
job_requests_map_[job.get()].insert(request);
- active_jobs_[host_port_proxy_pair] = job.release();
+ active_jobs_[key] = job.release();
}
if (rv == OK) {
- DCHECK(HasActiveSession(host_port_proxy_pair));
- request->set_stream(CreateIfSessionExists(host_port_proxy_pair, net_log));
+ DCHECK(HasActiveSession(key));
+ request->set_stream(CreateIfSessionExists(key, net_log));
}
return rv;
}
bool QuicStreamFactory::OnResolution(
- const HostPortProxyPair& host_port_proxy_pair,
+ const SessionKey& session_key,
const AddressList& address_list) {
- DCHECK(!HasActiveSession(host_port_proxy_pair));
+ DCHECK(!HasActiveSession(session_key));
for (size_t i = 0; i < address_list.size(); ++i) {
const IPEndPoint& address = address_list[i];
- if (!ContainsKey(ip_aliases_, address))
+ const IpAliasKey ip_alias_key(address, session_key.is_https);
+ if (!ContainsKey(ip_aliases_, ip_alias_key))
continue;
- const SessionSet& sessions = ip_aliases_[address];
+ const SessionSet& sessions = ip_aliases_[ip_alias_key];
for (SessionSet::const_iterator i = sessions.begin();
i != sessions.end(); ++i) {
QuicClientSession* session = *i;
- if (!session->CanPool(host_port_proxy_pair.first.host()))
+ if (!session->CanPool(session_key.host_port_proxy_pair.first.host()))
continue;
- active_sessions_[host_port_proxy_pair] = session;
- session_aliases_[session].insert(host_port_proxy_pair);
+ active_sessions_[session_key] = session;
+ session_aliases_[session].insert(session_key);
return true;
}
}
@@ -384,8 +438,8 @@ void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
// Create all the streams, but do not notify them yet.
for (RequestSet::iterator it = job_requests_map_[job].begin();
it != job_requests_map_[job].end() ; ++it) {
- DCHECK(HasActiveSession(job->host_port_proxy_pair()));
- (*it)->set_stream(CreateIfSessionExists(job->host_port_proxy_pair(),
+ DCHECK(HasActiveSession(job->session_key()));
+ (*it)->set_stream(CreateIfSessionExists(job->session_key(),
(*it)->net_log()));
}
}
@@ -399,7 +453,7 @@ void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
// profile which can not be deleted via callbacks.
request->OnRequestComplete(rv);
}
- active_jobs_.erase(job->host_port_proxy_pair());
+ active_jobs_.erase(job->session_key());
job_requests_map_.erase(job);
delete job;
return;
@@ -408,14 +462,14 @@ void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
// Returns a newly created QuicHttpStream owned by the caller, if a
// matching session already exists. Returns NULL otherwise.
scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists(
- const HostPortProxyPair& host_port_proxy_pair,
+ const SessionKey& session_key,
const BoundNetLog& net_log) {
- if (!HasActiveSession(host_port_proxy_pair)) {
+ if (!HasActiveSession(session_key)) {
DVLOG(1) << "No active session";
return scoped_ptr<QuicHttpStream>();
}
- QuicClientSession* session = active_sessions_[host_port_proxy_pair];
+ QuicClientSession* session = active_sessions_[session_key];
DCHECK(session);
return scoped_ptr<QuicHttpStream>(
new QuicHttpStream(session->GetWeakPtr()));
@@ -445,20 +499,24 @@ void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) {
// packets from the peer, we should consider blacklisting this
// differently so that we still race TCP but we don't consider the
// session connected until the handshake has been confirmed.
- http_server_properties_->SetBrokenAlternateProtocol(it->first);
+ http_server_properties_->SetBrokenAlternateProtocol(
+ it->host_port_proxy_pair.first);
} else {
QuicConnectionStats stats = session->connection()->GetStats();
HttpServerProperties::NetworkStats network_stats;
network_stats.rtt = base::TimeDelta::FromMicroseconds(stats.rtt);
network_stats.bandwidth_estimate = stats.estimated_bandwidth;
http_server_properties_->SetServerNetworkStats(
- it->first, network_stats);
+ it->host_port_proxy_pair.first, network_stats);
}
}
- IPEndPoint peer_address = session->connection()->peer_address();
- ip_aliases_[peer_address].erase(session);
- if (ip_aliases_[peer_address].empty()) {
- ip_aliases_.erase(peer_address);
+ if (!aliases.empty()) {
+ const IpAliasKey ip_alias_key(session->connection()->peer_address(),
+ aliases.begin()->is_https);
+ ip_aliases_[ip_alias_key].erase(session);
+ if (ip_aliases_[ip_alias_key].empty()) {
+ ip_aliases_.erase(ip_alias_key);
+ }
}
session_aliases_.erase(session);
}
@@ -496,12 +554,17 @@ base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const {
for (SessionMap::const_iterator it = active_sessions_.begin();
it != active_sessions_.end(); ++it) {
- const HostPortProxyPair& pair = it->first;
+ const SessionKey& session_key = it->first;
QuicClientSession* session = it->second;
const AliasSet& aliases = session_aliases_.find(session)->second;
- if (pair.first.Equals(aliases.begin()->first) &&
- pair.second == aliases.begin()->second) {
- list->Append(session->GetInfoAsValue(aliases));
+ // Only add a session to the list once.
+ if (session_key == *aliases.begin()) {
+ std::set<HostPortProxyPair> hosts;
+ for (AliasSet::const_iterator alias_it = aliases.begin();
+ alias_it != aliases.end(); ++alias_it) {
+ hosts.insert(alias_it->host_port_proxy_pair);
+ }
+ list->Append(session->GetInfoAsValue(hosts));
}
}
return list;
@@ -529,9 +592,8 @@ void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) {
CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
}
-bool QuicStreamFactory::HasActiveSession(
- const HostPortProxyPair& host_port_proxy_pair) {
- return ContainsKey(active_sessions_, host_port_proxy_pair);
+bool QuicStreamFactory::HasActiveSession(const SessionKey& session_key) const {
+ return ContainsKey(active_sessions_, session_key);
}
int QuicStreamFactory::CreateSession(
@@ -542,13 +604,14 @@ int QuicStreamFactory::CreateSession(
const BoundNetLog& net_log,
QuicClientSession** session) {
bool enable_port_selection = enable_port_selection_;
+ SessionKey session_key(host_port_proxy_pair, is_https);
if (enable_port_selection &&
- ContainsKey(gone_away_aliases_, host_port_proxy_pair)) {
+ ContainsKey(gone_away_aliases_, session_key)) {
// Disable port selection when the server is going away.
// There is no point in trying to return to the same server, if
// that server is no longer handling requests.
enable_port_selection = false;
- gone_away_aliases_.erase(host_port_proxy_pair);
+ gone_away_aliases_.erase(session_key);
}
QuicConnectionId connection_id = random_generator_->RandUint64();
@@ -628,20 +691,20 @@ int QuicStreamFactory::CreateSession(
return OK;
}
-bool QuicStreamFactory::HasActiveJob(
- const HostPortProxyPair& host_port_proxy_pair) {
- return ContainsKey(active_jobs_, host_port_proxy_pair);
+bool QuicStreamFactory::HasActiveJob(const SessionKey& key) const {
+ return ContainsKey(active_jobs_, key);
}
void QuicStreamFactory::ActivateSession(
- const HostPortProxyPair& host_port_proxy_pair,
+ const SessionKey& session_key,
QuicClientSession* session) {
- DCHECK(!HasActiveSession(host_port_proxy_pair));
- active_sessions_[host_port_proxy_pair] = session;
- session_aliases_[session].insert(host_port_proxy_pair);
- DCHECK(!ContainsKey(ip_aliases_[session->connection()->peer_address()],
- session));
- ip_aliases_[session->connection()->peer_address()].insert(session);
+ DCHECK(!HasActiveSession(session_key));
+ active_sessions_[session_key] = session;
+ session_aliases_[session].insert(session_key);
+ const IpAliasKey ip_alias_key(session->connection()->peer_address(),
+ session_key.is_https);
+ DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session));
+ ip_aliases_[ip_alias_key].insert(session);
}
QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig(

Powered by Google App Engine
This is Rietveld 408576698