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

Side by Side 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 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_stream_factory.h" 5 #include "net/quic/quic_stream_factory.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/message_loop/message_loop_proxy.h"
(...skipping 20 matching lines...) Expand all
31 #include "net/quic/quic_default_packet_writer.h" 31 #include "net/quic/quic_default_packet_writer.h"
32 #include "net/quic/quic_http_stream.h" 32 #include "net/quic/quic_http_stream.h"
33 #include "net/quic/quic_protocol.h" 33 #include "net/quic/quic_protocol.h"
34 #include "net/socket/client_socket_factory.h" 34 #include "net/socket/client_socket_factory.h"
35 35
36 using std::string; 36 using std::string;
37 using std::vector; 37 using std::vector;
38 38
39 namespace net { 39 namespace net {
40 40
41 QuicStreamFactory::SessionKey::SessionKey() {}
42
43 QuicStreamFactory::SessionKey::SessionKey(
44 HostPortProxyPair host_port_proxy_pair,
45 bool is_https)
46 : host_port_proxy_pair(host_port_proxy_pair),
47 is_https(is_https) {}
48
49 QuicStreamFactory::SessionKey::~SessionKey() {}
50
51 bool QuicStreamFactory::SessionKey::operator<(
52 const QuicStreamFactory::SessionKey &other) const {
53 if (!host_port_proxy_pair.first.Equals(other.host_port_proxy_pair.first)) {
54 return host_port_proxy_pair.first < other.host_port_proxy_pair.first;
55 }
56 if (!(host_port_proxy_pair.second == other.host_port_proxy_pair.second)) {
57 return host_port_proxy_pair.second < other.host_port_proxy_pair.second;
58 }
59 return is_https < other.is_https;
60 }
61
62 bool QuicStreamFactory::SessionKey::operator==(
63 const QuicStreamFactory::SessionKey& other) const {
64 return is_https == other.is_https &&
65 host_port_proxy_pair.second == other.host_port_proxy_pair.second &&
66 host_port_proxy_pair.first.Equals(other.host_port_proxy_pair.first);
67 };
68
69 QuicStreamFactory::IpAliasKey::IpAliasKey() {}
70
71 QuicStreamFactory::IpAliasKey::IpAliasKey(IPEndPoint ip_endpoint,
72 bool is_https)
73 : ip_endpoint(ip_endpoint),
74 is_https(is_https) {}
75
76 QuicStreamFactory::IpAliasKey::~IpAliasKey() {}
77
78 bool QuicStreamFactory::IpAliasKey::operator<(
79 const QuicStreamFactory::IpAliasKey& other) const {
80 if (!(ip_endpoint == other.ip_endpoint)) {
81 return ip_endpoint < other.ip_endpoint;
82 }
83 return is_https < other.is_https;
84 }
85
86 bool QuicStreamFactory::IpAliasKey::operator==(
87 const QuicStreamFactory::IpAliasKey& other) const {
88 return is_https == other.is_https &&
89 ip_endpoint == other.ip_endpoint;
90 };
91
41 // Responsible for creating a new QUIC session to the specified server, and 92 // Responsible for creating a new QUIC session to the specified server, and
42 // for notifying any associated requests when complete. 93 // for notifying any associated requests when complete.
43 class QuicStreamFactory::Job { 94 class QuicStreamFactory::Job {
44 public: 95 public:
45 Job(QuicStreamFactory* factory, 96 Job(QuicStreamFactory* factory,
46 HostResolver* host_resolver, 97 HostResolver* host_resolver,
47 const HostPortProxyPair& host_port_proxy_pair, 98 const HostPortProxyPair& host_port_proxy_pair,
48 bool is_https, 99 bool is_https,
49 base::StringPiece method, 100 base::StringPiece method,
50 CertVerifier* cert_verifier, 101 CertVerifier* cert_verifier,
51 const BoundNetLog& net_log); 102 const BoundNetLog& net_log);
52 103
53 ~Job(); 104 ~Job();
54 105
55 int Run(const CompletionCallback& callback); 106 int Run(const CompletionCallback& callback);
56 107
57 int DoLoop(int rv); 108 int DoLoop(int rv);
58 int DoResolveHost(); 109 int DoResolveHost();
59 int DoResolveHostComplete(int rv); 110 int DoResolveHostComplete(int rv);
60 int DoConnect(); 111 int DoConnect();
61 int DoConnectComplete(int rv); 112 int DoConnectComplete(int rv);
62 113
63 void OnIOComplete(int rv); 114 void OnIOComplete(int rv);
64 115
65 CompletionCallback callback() { 116 CompletionCallback callback() {
66 return callback_; 117 return callback_;
67 } 118 }
68 119
69 const HostPortProxyPair& host_port_proxy_pair() const { 120 const SessionKey session_key() const {
70 return host_port_proxy_pair_; 121 return session_key_;
71 } 122 }
72 123
73 private: 124 private:
74 enum IoState { 125 enum IoState {
75 STATE_NONE, 126 STATE_NONE,
76 STATE_RESOLVE_HOST, 127 STATE_RESOLVE_HOST,
77 STATE_RESOLVE_HOST_COMPLETE, 128 STATE_RESOLVE_HOST_COMPLETE,
78 STATE_CONNECT, 129 STATE_CONNECT,
79 STATE_CONNECT_COMPLETE, 130 STATE_CONNECT_COMPLETE,
80 }; 131 };
81 IoState io_state_; 132 IoState io_state_;
82 133
83 QuicStreamFactory* factory_; 134 QuicStreamFactory* factory_;
84 SingleRequestHostResolver host_resolver_; 135 SingleRequestHostResolver host_resolver_;
85 const HostPortProxyPair host_port_proxy_pair_;
86 bool is_https_; 136 bool is_https_;
137 SessionKey session_key_;
87 bool is_post_; 138 bool is_post_;
88 CertVerifier* cert_verifier_; 139 CertVerifier* cert_verifier_;
89 const BoundNetLog net_log_; 140 const BoundNetLog net_log_;
90 QuicClientSession* session_; 141 QuicClientSession* session_;
91 CompletionCallback callback_; 142 CompletionCallback callback_;
92 AddressList address_list_; 143 AddressList address_list_;
93 DISALLOW_COPY_AND_ASSIGN(Job); 144 DISALLOW_COPY_AND_ASSIGN(Job);
94 }; 145 };
95 146
96 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, 147 QuicStreamFactory::Job::Job(QuicStreamFactory* factory,
97 HostResolver* host_resolver, 148 HostResolver* host_resolver,
98 const HostPortProxyPair& host_port_proxy_pair, 149 const HostPortProxyPair& host_port_proxy_pair,
99 bool is_https, 150 bool is_https,
100 base::StringPiece method, 151 base::StringPiece method,
101 CertVerifier* cert_verifier, 152 CertVerifier* cert_verifier,
102 const BoundNetLog& net_log) 153 const BoundNetLog& net_log)
103 : factory_(factory), 154 : factory_(factory),
104 host_resolver_(host_resolver), 155 host_resolver_(host_resolver),
105 host_port_proxy_pair_(host_port_proxy_pair),
106 is_https_(is_https), 156 is_https_(is_https),
157 session_key_(host_port_proxy_pair, is_https),
107 is_post_(method == "POST"), 158 is_post_(method == "POST"),
108 cert_verifier_(cert_verifier), 159 cert_verifier_(cert_verifier),
109 net_log_(net_log), 160 net_log_(net_log),
110 session_(NULL) {} 161 session_(NULL) {}
111 162
112 QuicStreamFactory::Job::~Job() { 163 QuicStreamFactory::Job::~Job() {
113 } 164 }
114 165
115 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { 166 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) {
116 io_state_ = STATE_RESOLVE_HOST; 167 io_state_ = STATE_RESOLVE_HOST;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 rv = DoLoop(rv); 203 rv = DoLoop(rv);
153 204
154 if (rv != ERR_IO_PENDING && !callback_.is_null()) { 205 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
155 callback_.Run(rv); 206 callback_.Run(rv);
156 } 207 }
157 } 208 }
158 209
159 int QuicStreamFactory::Job::DoResolveHost() { 210 int QuicStreamFactory::Job::DoResolveHost() {
160 io_state_ = STATE_RESOLVE_HOST_COMPLETE; 211 io_state_ = STATE_RESOLVE_HOST_COMPLETE;
161 return host_resolver_.Resolve( 212 return host_resolver_.Resolve(
162 HostResolver::RequestInfo(host_port_proxy_pair_.first), 213 HostResolver::RequestInfo(session_key_.host_port_proxy_pair.first),
163 DEFAULT_PRIORITY, 214 DEFAULT_PRIORITY,
164 &address_list_, 215 &address_list_,
165 base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)), 216 base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)),
166 net_log_); 217 net_log_);
167 } 218 }
168 219
169 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { 220 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) {
170 if (rv != OK) 221 if (rv != OK)
171 return rv; 222 return rv;
172 223
173 DCHECK(!factory_->HasActiveSession(host_port_proxy_pair_)); 224 DCHECK(!factory_->HasActiveSession(session_key_));
174 225
175 // Inform the factory of this resolution, which will set up 226 // Inform the factory of this resolution, which will set up
176 // a session alias, if possible. 227 // a session alias, if possible.
177 if (factory_->OnResolution(host_port_proxy_pair_, address_list_)) { 228 if (factory_->OnResolution(session_key_, address_list_)) {
178 return OK; 229 return OK;
179 } 230 }
180 231
181 io_state_ = STATE_CONNECT; 232 io_state_ = STATE_CONNECT;
182 return OK; 233 return OK;
183 } 234 }
184 235
185 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) 236 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory)
186 : factory_(factory) {} 237 : factory_(factory) {}
187 238
188 QuicStreamRequest::~QuicStreamRequest() { 239 QuicStreamRequest::~QuicStreamRequest() {
189 if (factory_ && !callback_.is_null()) 240 if (factory_ && !callback_.is_null())
190 factory_->CancelRequest(this); 241 factory_->CancelRequest(this);
191 } 242 }
192 243
193 int QuicStreamRequest::Request(const HostPortProxyPair& host_port_proxy_pair, 244 int QuicStreamRequest::Request(const HostPortProxyPair& host_port_proxy_pair,
194 bool is_https, 245 bool is_https,
195 base::StringPiece method, 246 base::StringPiece method,
196 CertVerifier* cert_verifier, 247 CertVerifier* cert_verifier,
197 const BoundNetLog& net_log, 248 const BoundNetLog& net_log,
198 const CompletionCallback& callback) { 249 const CompletionCallback& callback) {
199 DCHECK(!stream_); 250 DCHECK(!stream_);
200 DCHECK(callback_.is_null()); 251 DCHECK(callback_.is_null());
201 DCHECK(factory_); 252 DCHECK(factory_);
202 int rv = factory_->Create( 253 int rv = factory_->Create(host_port_proxy_pair, is_https,
203 host_port_proxy_pair, is_https, method, cert_verifier, net_log, this); 254 method, cert_verifier, net_log, this);
204 if (rv == ERR_IO_PENDING) { 255 if (rv == ERR_IO_PENDING) {
205 host_port_proxy_pair_ = host_port_proxy_pair; 256 host_port_proxy_pair_ = host_port_proxy_pair;
206 is_https_ = is_https; 257 is_https_ = is_https;
207 cert_verifier_ = cert_verifier; 258 cert_verifier_ = cert_verifier;
208 net_log_ = net_log; 259 net_log_ = net_log;
209 callback_ = callback; 260 callback_ = callback;
210 } else { 261 } else {
211 factory_ = NULL; 262 factory_ = NULL;
212 } 263 }
213 if (rv == OK) 264 if (rv == OK)
(...skipping 12 matching lines...) Expand all
226 } 277 }
227 278
228 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { 279 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() {
229 DCHECK(stream_); 280 DCHECK(stream_);
230 return stream_.Pass(); 281 return stream_.Pass();
231 } 282 }
232 283
233 int QuicStreamFactory::Job::DoConnect() { 284 int QuicStreamFactory::Job::DoConnect() {
234 io_state_ = STATE_CONNECT_COMPLETE; 285 io_state_ = STATE_CONNECT_COMPLETE;
235 286
236 int rv = factory_->CreateSession(host_port_proxy_pair_, is_https_, 287 int rv = factory_->CreateSession(session_key_.host_port_proxy_pair, is_https_,
237 cert_verifier_, address_list_, net_log_, &session_); 288 cert_verifier_, address_list_, net_log_, &session_);
238 if (rv != OK) { 289 if (rv != OK) {
239 DCHECK(rv != ERR_IO_PENDING); 290 DCHECK(rv != ERR_IO_PENDING);
240 DCHECK(!session_); 291 DCHECK(!session_);
241 return rv; 292 return rv;
242 } 293 }
243 294
244 session_->StartReading(); 295 session_->StartReading();
245 if (!session_->connection()->connected()) { 296 if (!session_->connection()->connected()) {
246 return ERR_QUIC_PROTOCOL_ERROR; 297 return ERR_QUIC_PROTOCOL_ERROR;
247 } 298 }
248 rv = session_->CryptoConnect( 299 rv = session_->CryptoConnect(
249 factory_->require_confirmation() || is_https_, 300 factory_->require_confirmation() || is_https_,
250 base::Bind(&QuicStreamFactory::Job::OnIOComplete, 301 base::Bind(&QuicStreamFactory::Job::OnIOComplete,
251 base::Unretained(this))); 302 base::Unretained(this)));
252 return rv; 303 return rv;
253 } 304 }
254 305
255 int QuicStreamFactory::Job::DoConnectComplete(int rv) { 306 int QuicStreamFactory::Job::DoConnectComplete(int rv) {
256 if (rv != OK) 307 if (rv != OK)
257 return rv; 308 return rv;
258 309
259 DCHECK(!factory_->HasActiveSession(host_port_proxy_pair_)); 310 DCHECK(!factory_->HasActiveSession(session_key_));
260 // There may well now be an active session for this IP. If so, use the 311 // There may well now be an active session for this IP. If so, use the
261 // existing session instead. 312 // existing session instead.
262 AddressList address(session_->connection()->peer_address()); 313 AddressList address(session_->connection()->peer_address());
263 if (factory_->OnResolution(host_port_proxy_pair_, address)) { 314 if (factory_->OnResolution(session_key_, address)) {
315
264 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); 316 session_->connection()->SendConnectionClose(QUIC_NO_ERROR);
265 session_ = NULL; 317 session_ = NULL;
266 return OK; 318 return OK;
267 } 319 }
268 320
269 factory_->ActivateSession(host_port_proxy_pair_, session_); 321 factory_->ActivateSession(session_key_, session_);
270 322
271 return OK; 323 return OK;
272 } 324 }
273 325
274 QuicStreamFactory::QuicStreamFactory( 326 QuicStreamFactory::QuicStreamFactory(
275 HostResolver* host_resolver, 327 HostResolver* host_resolver,
276 ClientSocketFactory* client_socket_factory, 328 ClientSocketFactory* client_socket_factory,
277 base::WeakPtr<HttpServerProperties> http_server_properties, 329 base::WeakPtr<HttpServerProperties> http_server_properties,
278 QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, 330 QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory,
279 QuicRandom* random_generator, 331 QuicRandom* random_generator,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 STLDeleteValues(&active_jobs_); 364 STLDeleteValues(&active_jobs_);
313 STLDeleteValues(&all_crypto_configs_); 365 STLDeleteValues(&all_crypto_configs_);
314 } 366 }
315 367
316 int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair, 368 int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair,
317 bool is_https, 369 bool is_https,
318 base::StringPiece method, 370 base::StringPiece method,
319 CertVerifier* cert_verifier, 371 CertVerifier* cert_verifier,
320 const BoundNetLog& net_log, 372 const BoundNetLog& net_log,
321 QuicStreamRequest* request) { 373 QuicStreamRequest* request) {
322 if (HasActiveSession(host_port_proxy_pair)) { 374 SessionKey key(host_port_proxy_pair, is_https);
323 request->set_stream(CreateIfSessionExists(host_port_proxy_pair, net_log)); 375 if (HasActiveSession(key)) {
376 request->set_stream(CreateIfSessionExists(key, net_log));
324 return OK; 377 return OK;
325 } 378 }
326 379
327 if (HasActiveJob(host_port_proxy_pair)) { 380 if (HasActiveJob(key)) {
328 Job* job = active_jobs_[host_port_proxy_pair]; 381 Job* job = active_jobs_[key];
329 active_requests_[request] = job; 382 active_requests_[request] = job;
330 job_requests_map_[job].insert(request); 383 job_requests_map_[job].insert(request);
331 return ERR_IO_PENDING; 384 return ERR_IO_PENDING;
332 } 385 }
333 386
334 // Create crypto config and start the process of loading QUIC server 387 // Create crypto config and start the process of loading QUIC server
335 // information from disk cache. 388 // information from disk cache.
336 QuicCryptoClientConfig* crypto_config = 389 QuicCryptoClientConfig* crypto_config =
337 GetOrCreateCryptoConfig(host_port_proxy_pair); 390 GetOrCreateCryptoConfig(host_port_proxy_pair);
338 DCHECK(crypto_config); 391 DCHECK(crypto_config);
339 392
340 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_proxy_pair, 393 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_proxy_pair,
341 is_https, method, cert_verifier, net_log)); 394 is_https, method, cert_verifier, net_log));
342 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, 395 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete,
343 base::Unretained(this), job.get())); 396 base::Unretained(this), job.get()));
344 397
345 if (rv == ERR_IO_PENDING) { 398 if (rv == ERR_IO_PENDING) {
346 active_requests_[request] = job.get(); 399 active_requests_[request] = job.get();
347 job_requests_map_[job.get()].insert(request); 400 job_requests_map_[job.get()].insert(request);
348 active_jobs_[host_port_proxy_pair] = job.release(); 401 active_jobs_[key] = job.release();
349 } 402 }
350 if (rv == OK) { 403 if (rv == OK) {
351 DCHECK(HasActiveSession(host_port_proxy_pair)); 404 DCHECK(HasActiveSession(key));
352 request->set_stream(CreateIfSessionExists(host_port_proxy_pair, net_log)); 405 request->set_stream(CreateIfSessionExists(key, net_log));
353 } 406 }
354 return rv; 407 return rv;
355 } 408 }
356 409
357 bool QuicStreamFactory::OnResolution( 410 bool QuicStreamFactory::OnResolution(
358 const HostPortProxyPair& host_port_proxy_pair, 411 const SessionKey& session_key,
359 const AddressList& address_list) { 412 const AddressList& address_list) {
360 DCHECK(!HasActiveSession(host_port_proxy_pair)); 413 DCHECK(!HasActiveSession(session_key));
361 for (size_t i = 0; i < address_list.size(); ++i) { 414 for (size_t i = 0; i < address_list.size(); ++i) {
362 const IPEndPoint& address = address_list[i]; 415 const IPEndPoint& address = address_list[i];
363 if (!ContainsKey(ip_aliases_, address)) 416 const IpAliasKey ip_alias_key(address, session_key.is_https);
417 if (!ContainsKey(ip_aliases_, ip_alias_key))
364 continue; 418 continue;
365 419
366 const SessionSet& sessions = ip_aliases_[address]; 420 const SessionSet& sessions = ip_aliases_[ip_alias_key];
367 for (SessionSet::const_iterator i = sessions.begin(); 421 for (SessionSet::const_iterator i = sessions.begin();
368 i != sessions.end(); ++i) { 422 i != sessions.end(); ++i) {
369 QuicClientSession* session = *i; 423 QuicClientSession* session = *i;
370 if (!session->CanPool(host_port_proxy_pair.first.host())) 424 if (!session->CanPool(session_key.host_port_proxy_pair.first.host()))
371 continue; 425 continue;
372 active_sessions_[host_port_proxy_pair] = session; 426 active_sessions_[session_key] = session;
373 session_aliases_[session].insert(host_port_proxy_pair); 427 session_aliases_[session].insert(session_key);
374 return true; 428 return true;
375 } 429 }
376 } 430 }
377 return false; 431 return false;
378 } 432 }
379 433
380 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { 434 void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
381 if (rv == OK) { 435 if (rv == OK) {
382 require_confirmation_ = false; 436 require_confirmation_ = false;
383 437
384 // Create all the streams, but do not notify them yet. 438 // Create all the streams, but do not notify them yet.
385 for (RequestSet::iterator it = job_requests_map_[job].begin(); 439 for (RequestSet::iterator it = job_requests_map_[job].begin();
386 it != job_requests_map_[job].end() ; ++it) { 440 it != job_requests_map_[job].end() ; ++it) {
387 DCHECK(HasActiveSession(job->host_port_proxy_pair())); 441 DCHECK(HasActiveSession(job->session_key()));
388 (*it)->set_stream(CreateIfSessionExists(job->host_port_proxy_pair(), 442 (*it)->set_stream(CreateIfSessionExists(job->session_key(),
389 (*it)->net_log())); 443 (*it)->net_log()));
390 } 444 }
391 } 445 }
392 while (!job_requests_map_[job].empty()) { 446 while (!job_requests_map_[job].empty()) {
393 RequestSet::iterator it = job_requests_map_[job].begin(); 447 RequestSet::iterator it = job_requests_map_[job].begin();
394 QuicStreamRequest* request = *it; 448 QuicStreamRequest* request = *it;
395 job_requests_map_[job].erase(it); 449 job_requests_map_[job].erase(it);
396 active_requests_.erase(request); 450 active_requests_.erase(request);
397 // Even though we're invoking callbacks here, we don't need to worry 451 // Even though we're invoking callbacks here, we don't need to worry
398 // about |this| being deleted, because the factory is owned by the 452 // about |this| being deleted, because the factory is owned by the
399 // profile which can not be deleted via callbacks. 453 // profile which can not be deleted via callbacks.
400 request->OnRequestComplete(rv); 454 request->OnRequestComplete(rv);
401 } 455 }
402 active_jobs_.erase(job->host_port_proxy_pair()); 456 active_jobs_.erase(job->session_key());
403 job_requests_map_.erase(job); 457 job_requests_map_.erase(job);
404 delete job; 458 delete job;
405 return; 459 return;
406 } 460 }
407 461
408 // Returns a newly created QuicHttpStream owned by the caller, if a 462 // Returns a newly created QuicHttpStream owned by the caller, if a
409 // matching session already exists. Returns NULL otherwise. 463 // matching session already exists. Returns NULL otherwise.
410 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( 464 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists(
411 const HostPortProxyPair& host_port_proxy_pair, 465 const SessionKey& session_key,
412 const BoundNetLog& net_log) { 466 const BoundNetLog& net_log) {
413 if (!HasActiveSession(host_port_proxy_pair)) { 467 if (!HasActiveSession(session_key)) {
414 DVLOG(1) << "No active session"; 468 DVLOG(1) << "No active session";
415 return scoped_ptr<QuicHttpStream>(); 469 return scoped_ptr<QuicHttpStream>();
416 } 470 }
417 471
418 QuicClientSession* session = active_sessions_[host_port_proxy_pair]; 472 QuicClientSession* session = active_sessions_[session_key];
419 DCHECK(session); 473 DCHECK(session);
420 return scoped_ptr<QuicHttpStream>( 474 return scoped_ptr<QuicHttpStream>(
421 new QuicHttpStream(session->GetWeakPtr())); 475 new QuicHttpStream(session->GetWeakPtr()));
422 } 476 }
423 477
424 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { 478 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) {
425 } 479 }
426 480
427 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { 481 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) {
428 const AliasSet& aliases = session_aliases_[session]; 482 const AliasSet& aliases = session_aliases_[session];
429 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); 483 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end();
430 ++it) { 484 ++it) {
431 DCHECK(active_sessions_.count(*it)); 485 DCHECK(active_sessions_.count(*it));
432 DCHECK_EQ(session, active_sessions_[*it]); 486 DCHECK_EQ(session, active_sessions_[*it]);
433 // Track sessions which have recently gone away so that we can disable 487 // Track sessions which have recently gone away so that we can disable
434 // port suggestions. 488 // port suggestions.
435 if (session->goaway_received()) { 489 if (session->goaway_received()) {
436 gone_away_aliases_.insert(*it); 490 gone_away_aliases_.insert(*it);
437 } 491 }
438 492
439 active_sessions_.erase(*it); 493 active_sessions_.erase(*it);
440 if (!http_server_properties_) 494 if (!http_server_properties_)
441 continue; 495 continue;
442 496
443 if (!session->IsCryptoHandshakeConfirmed()) { 497 if (!session->IsCryptoHandshakeConfirmed()) {
444 // TODO(rch): In the special case where the session has received no 498 // TODO(rch): In the special case where the session has received no
445 // packets from the peer, we should consider blacklisting this 499 // packets from the peer, we should consider blacklisting this
446 // differently so that we still race TCP but we don't consider the 500 // differently so that we still race TCP but we don't consider the
447 // session connected until the handshake has been confirmed. 501 // session connected until the handshake has been confirmed.
448 http_server_properties_->SetBrokenAlternateProtocol(it->first); 502 http_server_properties_->SetBrokenAlternateProtocol(
503 it->host_port_proxy_pair.first);
449 } else { 504 } else {
450 QuicConnectionStats stats = session->connection()->GetStats(); 505 QuicConnectionStats stats = session->connection()->GetStats();
451 HttpServerProperties::NetworkStats network_stats; 506 HttpServerProperties::NetworkStats network_stats;
452 network_stats.rtt = base::TimeDelta::FromMicroseconds(stats.rtt); 507 network_stats.rtt = base::TimeDelta::FromMicroseconds(stats.rtt);
453 network_stats.bandwidth_estimate = stats.estimated_bandwidth; 508 network_stats.bandwidth_estimate = stats.estimated_bandwidth;
454 http_server_properties_->SetServerNetworkStats( 509 http_server_properties_->SetServerNetworkStats(
455 it->first, network_stats); 510 it->host_port_proxy_pair.first, network_stats);
456 } 511 }
457 } 512 }
458 IPEndPoint peer_address = session->connection()->peer_address(); 513 if (!aliases.empty()) {
459 ip_aliases_[peer_address].erase(session); 514 const IpAliasKey ip_alias_key(session->connection()->peer_address(),
460 if (ip_aliases_[peer_address].empty()) { 515 aliases.begin()->is_https);
461 ip_aliases_.erase(peer_address); 516 ip_aliases_[ip_alias_key].erase(session);
517 if (ip_aliases_[ip_alias_key].empty()) {
518 ip_aliases_.erase(ip_alias_key);
519 }
462 } 520 }
463 session_aliases_.erase(session); 521 session_aliases_.erase(session);
464 } 522 }
465 523
466 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { 524 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) {
467 DCHECK_EQ(0u, session->GetNumOpenStreams()); 525 DCHECK_EQ(0u, session->GetNumOpenStreams());
468 OnSessionGoingAway(session); 526 OnSessionGoingAway(session);
469 all_sessions_.erase(session); 527 all_sessions_.erase(session);
470 delete session; 528 delete session;
471 } 529 }
(...skipping 17 matching lines...) Expand all
489 DCHECK_NE(initial_size, all_sessions_.size()); 547 DCHECK_NE(initial_size, all_sessions_.size());
490 } 548 }
491 DCHECK(all_sessions_.empty()); 549 DCHECK(all_sessions_.empty());
492 } 550 }
493 551
494 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { 552 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const {
495 base::ListValue* list = new base::ListValue(); 553 base::ListValue* list = new base::ListValue();
496 554
497 for (SessionMap::const_iterator it = active_sessions_.begin(); 555 for (SessionMap::const_iterator it = active_sessions_.begin();
498 it != active_sessions_.end(); ++it) { 556 it != active_sessions_.end(); ++it) {
499 const HostPortProxyPair& pair = it->first; 557 const SessionKey& session_key = it->first;
500 QuicClientSession* session = it->second; 558 QuicClientSession* session = it->second;
501 const AliasSet& aliases = session_aliases_.find(session)->second; 559 const AliasSet& aliases = session_aliases_.find(session)->second;
502 if (pair.first.Equals(aliases.begin()->first) && 560 // Only add a session to the list once.
503 pair.second == aliases.begin()->second) { 561 if (session_key == *aliases.begin()) {
504 list->Append(session->GetInfoAsValue(aliases)); 562 std::set<HostPortProxyPair> hosts;
563 for (AliasSet::const_iterator alias_it = aliases.begin();
564 alias_it != aliases.end(); ++alias_it) {
565 hosts.insert(alias_it->host_port_proxy_pair);
566 }
567 list->Append(session->GetInfoAsValue(hosts));
505 } 568 }
506 } 569 }
507 return list; 570 return list;
508 } 571 }
509 572
510 void QuicStreamFactory::OnIPAddressChanged() { 573 void QuicStreamFactory::OnIPAddressChanged() {
511 CloseAllSessions(ERR_NETWORK_CHANGED); 574 CloseAllSessions(ERR_NETWORK_CHANGED);
512 require_confirmation_ = true; 575 require_confirmation_ = true;
513 } 576 }
514 577
515 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { 578 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) {
516 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); 579 CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
517 } 580 }
518 581
519 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { 582 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) {
520 // We should flush the sessions if we removed trust from a 583 // We should flush the sessions if we removed trust from a
521 // cert, because a previously trusted server may have become 584 // cert, because a previously trusted server may have become
522 // untrusted. 585 // untrusted.
523 // 586 //
524 // We should not flush the sessions if we added trust to a cert. 587 // We should not flush the sessions if we added trust to a cert.
525 // 588 //
526 // Since the OnCACertChanged method doesn't tell us what 589 // Since the OnCACertChanged method doesn't tell us what
527 // kind of change it is, we have to flush the socket 590 // kind of change it is, we have to flush the socket
528 // pools to be safe. 591 // pools to be safe.
529 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); 592 CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
530 } 593 }
531 594
532 bool QuicStreamFactory::HasActiveSession( 595 bool QuicStreamFactory::HasActiveSession(const SessionKey& session_key) const {
533 const HostPortProxyPair& host_port_proxy_pair) { 596 return ContainsKey(active_sessions_, session_key);
534 return ContainsKey(active_sessions_, host_port_proxy_pair);
535 } 597 }
536 598
537 int QuicStreamFactory::CreateSession( 599 int QuicStreamFactory::CreateSession(
538 const HostPortProxyPair& host_port_proxy_pair, 600 const HostPortProxyPair& host_port_proxy_pair,
539 bool is_https, 601 bool is_https,
540 CertVerifier* cert_verifier, 602 CertVerifier* cert_verifier,
541 const AddressList& address_list, 603 const AddressList& address_list,
542 const BoundNetLog& net_log, 604 const BoundNetLog& net_log,
543 QuicClientSession** session) { 605 QuicClientSession** session) {
544 bool enable_port_selection = enable_port_selection_; 606 bool enable_port_selection = enable_port_selection_;
607 SessionKey session_key(host_port_proxy_pair, is_https);
545 if (enable_port_selection && 608 if (enable_port_selection &&
546 ContainsKey(gone_away_aliases_, host_port_proxy_pair)) { 609 ContainsKey(gone_away_aliases_, session_key)) {
547 // Disable port selection when the server is going away. 610 // Disable port selection when the server is going away.
548 // There is no point in trying to return to the same server, if 611 // There is no point in trying to return to the same server, if
549 // that server is no longer handling requests. 612 // that server is no longer handling requests.
550 enable_port_selection = false; 613 enable_port_selection = false;
551 gone_away_aliases_.erase(host_port_proxy_pair); 614 gone_away_aliases_.erase(session_key);
552 } 615 }
553 616
554 QuicConnectionId connection_id = random_generator_->RandUint64(); 617 QuicConnectionId connection_id = random_generator_->RandUint64();
555 IPEndPoint addr = *address_list.begin(); 618 IPEndPoint addr = *address_list.begin();
556 scoped_refptr<PortSuggester> port_suggester = 619 scoped_refptr<PortSuggester> port_suggester =
557 new PortSuggester(host_port_proxy_pair.first, port_seed_); 620 new PortSuggester(host_port_proxy_pair.first, port_seed_);
558 DatagramSocket::BindType bind_type = enable_port_selection ? 621 DatagramSocket::BindType bind_type = enable_port_selection ?
559 DatagramSocket::RANDOM_BIND : // Use our callback. 622 DatagramSocket::RANDOM_BIND : // Use our callback.
560 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. 623 DatagramSocket::DEFAULT_BIND; // Use OS to randomize.
561 scoped_ptr<DatagramClientSocket> socket( 624 scoped_ptr<DatagramClientSocket> socket(
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(), 684 quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(),
622 config, crypto_config, net_log.net_log()); 685 config, crypto_config, net_log.net_log());
623 all_sessions_.insert(*session); // owning pointer 686 all_sessions_.insert(*session); // owning pointer
624 if (is_https) { 687 if (is_https) {
625 crypto_config->SetProofVerifier( 688 crypto_config->SetProofVerifier(
626 new ProofVerifierChromium(cert_verifier, net_log)); 689 new ProofVerifierChromium(cert_verifier, net_log));
627 } 690 }
628 return OK; 691 return OK;
629 } 692 }
630 693
631 bool QuicStreamFactory::HasActiveJob( 694 bool QuicStreamFactory::HasActiveJob(const SessionKey& key) const {
632 const HostPortProxyPair& host_port_proxy_pair) { 695 return ContainsKey(active_jobs_, key);
633 return ContainsKey(active_jobs_, host_port_proxy_pair);
634 } 696 }
635 697
636 void QuicStreamFactory::ActivateSession( 698 void QuicStreamFactory::ActivateSession(
637 const HostPortProxyPair& host_port_proxy_pair, 699 const SessionKey& session_key,
638 QuicClientSession* session) { 700 QuicClientSession* session) {
639 DCHECK(!HasActiveSession(host_port_proxy_pair)); 701 DCHECK(!HasActiveSession(session_key));
640 active_sessions_[host_port_proxy_pair] = session; 702 active_sessions_[session_key] = session;
641 session_aliases_[session].insert(host_port_proxy_pair); 703 session_aliases_[session].insert(session_key);
642 DCHECK(!ContainsKey(ip_aliases_[session->connection()->peer_address()], 704 const IpAliasKey ip_alias_key(session->connection()->peer_address(),
643 session)); 705 session_key.is_https);
644 ip_aliases_[session->connection()->peer_address()].insert(session); 706 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session));
707 ip_aliases_[ip_alias_key].insert(session);
645 } 708 }
646 709
647 QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig( 710 QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig(
648 const HostPortProxyPair& host_port_proxy_pair) { 711 const HostPortProxyPair& host_port_proxy_pair) {
649 QuicCryptoClientConfig* crypto_config; 712 QuicCryptoClientConfig* crypto_config;
650 713
651 if (ContainsKey(all_crypto_configs_, host_port_proxy_pair)) { 714 if (ContainsKey(all_crypto_configs_, host_port_proxy_pair)) {
652 crypto_config = all_crypto_configs_[host_port_proxy_pair]; 715 crypto_config = all_crypto_configs_[host_port_proxy_pair];
653 DCHECK(crypto_config); 716 DCHECK(crypto_config);
654 } else { 717 } else {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 // Copy the CachedState for the canonical server from canonical_crypto_config 764 // Copy the CachedState for the canonical server from canonical_crypto_config
702 // as the initial CachedState for the server_hostname in crypto_config. 765 // as the initial CachedState for the server_hostname in crypto_config.
703 crypto_config->InitializeFrom(server_hostname, 766 crypto_config->InitializeFrom(server_hostname,
704 canonical_host_port_proxy_pair.first.host(), 767 canonical_host_port_proxy_pair.first.host(),
705 canonical_crypto_config); 768 canonical_crypto_config);
706 // Update canonical version to point at the "most recent" crypto_config. 769 // Update canonical version to point at the "most recent" crypto_config.
707 canonical_hostname_to_origin_map_[canonical_host_port] = host_port_proxy_pair; 770 canonical_hostname_to_origin_map_[canonical_host_port] = host_port_proxy_pair;
708 } 771 }
709 772
710 } // namespace net 773 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698