OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_stream_factory.h" | 5 #include "net/quic/quic_stream_factory.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/cpu.h" | 9 #include "base/cpu.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "net/quic/crypto/quic_server_info.h" | 25 #include "net/quic/crypto/quic_server_info.h" |
26 #include "net/quic/port_suggester.h" | 26 #include "net/quic/port_suggester.h" |
27 #include "net/quic/quic_client_session.h" | 27 #include "net/quic/quic_client_session.h" |
28 #include "net/quic/quic_clock.h" | 28 #include "net/quic/quic_clock.h" |
29 #include "net/quic/quic_connection.h" | 29 #include "net/quic/quic_connection.h" |
30 #include "net/quic/quic_connection_helper.h" | 30 #include "net/quic/quic_connection_helper.h" |
31 #include "net/quic/quic_crypto_client_stream_factory.h" | 31 #include "net/quic/quic_crypto_client_stream_factory.h" |
32 #include "net/quic/quic_default_packet_writer.h" | 32 #include "net/quic/quic_default_packet_writer.h" |
33 #include "net/quic/quic_http_stream.h" | 33 #include "net/quic/quic_http_stream.h" |
34 #include "net/quic/quic_protocol.h" | 34 #include "net/quic/quic_protocol.h" |
35 #include "net/quic/quic_session_key.h" | 35 #include "net/quic/quic_server_id.h" |
36 #include "net/socket/client_socket_factory.h" | 36 #include "net/socket/client_socket_factory.h" |
37 | 37 |
38 using std::string; | 38 using std::string; |
39 using std::vector; | 39 using std::vector; |
40 | 40 |
41 namespace net { | 41 namespace net { |
42 | 42 |
43 namespace { | 43 namespace { |
44 | 44 |
45 enum CreateSessionFailure { | 45 enum CreateSessionFailure { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 int DoLoadServerInfoComplete(int rv); | 108 int DoLoadServerInfoComplete(int rv); |
109 int DoConnect(); | 109 int DoConnect(); |
110 int DoConnectComplete(int rv); | 110 int DoConnectComplete(int rv); |
111 | 111 |
112 void OnIOComplete(int rv); | 112 void OnIOComplete(int rv); |
113 | 113 |
114 CompletionCallback callback() { | 114 CompletionCallback callback() { |
115 return callback_; | 115 return callback_; |
116 } | 116 } |
117 | 117 |
118 const QuicSessionKey session_key() const { | 118 const QuicServerId server_id() const { |
119 return session_key_; | 119 return server_id_; |
120 } | 120 } |
121 | 121 |
122 private: | 122 private: |
123 enum IoState { | 123 enum IoState { |
124 STATE_NONE, | 124 STATE_NONE, |
125 STATE_RESOLVE_HOST, | 125 STATE_RESOLVE_HOST, |
126 STATE_RESOLVE_HOST_COMPLETE, | 126 STATE_RESOLVE_HOST_COMPLETE, |
127 STATE_LOAD_SERVER_INFO, | 127 STATE_LOAD_SERVER_INFO, |
128 STATE_LOAD_SERVER_INFO_COMPLETE, | 128 STATE_LOAD_SERVER_INFO_COMPLETE, |
129 STATE_CONNECT, | 129 STATE_CONNECT, |
130 STATE_CONNECT_COMPLETE, | 130 STATE_CONNECT_COMPLETE, |
131 }; | 131 }; |
132 IoState io_state_; | 132 IoState io_state_; |
133 | 133 |
134 QuicStreamFactory* factory_; | 134 QuicStreamFactory* factory_; |
135 SingleRequestHostResolver host_resolver_; | 135 SingleRequestHostResolver host_resolver_; |
136 QuicSessionKey session_key_; | 136 QuicServerId server_id_; |
137 bool is_post_; | 137 bool is_post_; |
138 scoped_ptr<QuicServerInfo> server_info_; | 138 scoped_ptr<QuicServerInfo> server_info_; |
139 const BoundNetLog net_log_; | 139 const BoundNetLog net_log_; |
140 QuicClientSession* session_; | 140 QuicClientSession* session_; |
141 CompletionCallback callback_; | 141 CompletionCallback callback_; |
142 AddressList address_list_; | 142 AddressList address_list_; |
143 base::TimeTicks disk_cache_load_start_time_; | 143 base::TimeTicks disk_cache_load_start_time_; |
144 base::WeakPtrFactory<Job> weak_factory_; | 144 base::WeakPtrFactory<Job> weak_factory_; |
145 DISALLOW_COPY_AND_ASSIGN(Job); | 145 DISALLOW_COPY_AND_ASSIGN(Job); |
146 }; | 146 }; |
147 | 147 |
148 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 148 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
149 HostResolver* host_resolver, | 149 HostResolver* host_resolver, |
150 const HostPortPair& host_port_pair, | 150 const HostPortPair& host_port_pair, |
151 bool is_https, | 151 bool is_https, |
152 PrivacyMode privacy_mode, | 152 PrivacyMode privacy_mode, |
153 base::StringPiece method, | 153 base::StringPiece method, |
154 QuicServerInfo* server_info, | 154 QuicServerInfo* server_info, |
155 const BoundNetLog& net_log) | 155 const BoundNetLog& net_log) |
156 : factory_(factory), | 156 : factory_(factory), |
157 host_resolver_(host_resolver), | 157 host_resolver_(host_resolver), |
158 session_key_(host_port_pair, is_https, privacy_mode), | 158 server_id_(host_port_pair, is_https, privacy_mode), |
159 is_post_(method == "POST"), | 159 is_post_(method == "POST"), |
160 server_info_(server_info), | 160 server_info_(server_info), |
161 net_log_(net_log), | 161 net_log_(net_log), |
162 session_(NULL), | 162 session_(NULL), |
163 weak_factory_(this) {} | 163 weak_factory_(this) {} |
164 | 164 |
165 QuicStreamFactory::Job::~Job() { | 165 QuicStreamFactory::Job::~Job() { |
166 } | 166 } |
167 | 167 |
168 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 168 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 | 218 |
219 int QuicStreamFactory::Job::DoResolveHost() { | 219 int QuicStreamFactory::Job::DoResolveHost() { |
220 // Start loading the data now, and wait for it after we resolve the host. | 220 // Start loading the data now, and wait for it after we resolve the host. |
221 if (server_info_) { | 221 if (server_info_) { |
222 disk_cache_load_start_time_ = base::TimeTicks::Now(); | 222 disk_cache_load_start_time_ = base::TimeTicks::Now(); |
223 server_info_->Start(); | 223 server_info_->Start(); |
224 } | 224 } |
225 | 225 |
226 io_state_ = STATE_RESOLVE_HOST_COMPLETE; | 226 io_state_ = STATE_RESOLVE_HOST_COMPLETE; |
227 return host_resolver_.Resolve( | 227 return host_resolver_.Resolve( |
228 HostResolver::RequestInfo(session_key_.host_port_pair()), | 228 HostResolver::RequestInfo(server_id_.host_port_pair()), |
229 DEFAULT_PRIORITY, | 229 DEFAULT_PRIORITY, |
230 &address_list_, | 230 &address_list_, |
231 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 231 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
232 weak_factory_.GetWeakPtr()), | 232 weak_factory_.GetWeakPtr()), |
233 net_log_); | 233 net_log_); |
234 } | 234 } |
235 | 235 |
236 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { | 236 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { |
237 if (rv != OK) | 237 if (rv != OK) |
238 return rv; | 238 return rv; |
239 | 239 |
240 DCHECK(!factory_->HasActiveSession(session_key_)); | 240 DCHECK(!factory_->HasActiveSession(server_id_)); |
241 | 241 |
242 // Inform the factory of this resolution, which will set up | 242 // Inform the factory of this resolution, which will set up |
243 // a session alias, if possible. | 243 // a session alias, if possible. |
244 if (factory_->OnResolution(session_key_, address_list_)) { | 244 if (factory_->OnResolution(server_id_, address_list_)) { |
245 return OK; | 245 return OK; |
246 } | 246 } |
247 | 247 |
248 io_state_ = STATE_LOAD_SERVER_INFO; | 248 io_state_ = STATE_LOAD_SERVER_INFO; |
249 return OK; | 249 return OK; |
250 } | 250 } |
251 | 251 |
252 int QuicStreamFactory::Job::DoLoadServerInfo() { | 252 int QuicStreamFactory::Job::DoLoadServerInfo() { |
253 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; | 253 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; |
254 | 254 |
(...skipping 15 matching lines...) Expand all Loading... |
270 server_info_.reset(); | 270 server_info_.reset(); |
271 } | 271 } |
272 | 272 |
273 io_state_ = STATE_CONNECT; | 273 io_state_ = STATE_CONNECT; |
274 return OK; | 274 return OK; |
275 } | 275 } |
276 | 276 |
277 int QuicStreamFactory::Job::DoConnect() { | 277 int QuicStreamFactory::Job::DoConnect() { |
278 io_state_ = STATE_CONNECT_COMPLETE; | 278 io_state_ = STATE_CONNECT_COMPLETE; |
279 | 279 |
280 int rv = factory_->CreateSession(session_key_, server_info_.Pass(), | 280 int rv = factory_->CreateSession(server_id_, server_info_.Pass(), |
281 address_list_, net_log_, &session_); | 281 address_list_, net_log_, &session_); |
282 if (rv != OK) { | 282 if (rv != OK) { |
283 DCHECK(rv != ERR_IO_PENDING); | 283 DCHECK(rv != ERR_IO_PENDING); |
284 DCHECK(!session_); | 284 DCHECK(!session_); |
285 return rv; | 285 return rv; |
286 } | 286 } |
287 | 287 |
288 session_->StartReading(); | 288 session_->StartReading(); |
289 if (!session_->connection()->connected()) { | 289 if (!session_->connection()->connected()) { |
290 return ERR_QUIC_PROTOCOL_ERROR; | 290 return ERR_QUIC_PROTOCOL_ERROR; |
291 } | 291 } |
292 rv = session_->CryptoConnect( | 292 rv = session_->CryptoConnect( |
293 factory_->require_confirmation() || session_key_.is_https() || is_post_, | 293 factory_->require_confirmation() || server_id_.is_https() || is_post_, |
294 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 294 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
295 base::Unretained(this))); | 295 base::Unretained(this))); |
296 return rv; | 296 return rv; |
297 } | 297 } |
298 | 298 |
299 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 299 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
300 if (rv != OK) | 300 if (rv != OK) |
301 return rv; | 301 return rv; |
302 | 302 |
303 DCHECK(!factory_->HasActiveSession(session_key_)); | 303 DCHECK(!factory_->HasActiveSession(server_id_)); |
304 // There may well now be an active session for this IP. If so, use the | 304 // There may well now be an active session for this IP. If so, use the |
305 // existing session instead. | 305 // existing session instead. |
306 AddressList address(session_->connection()->peer_address()); | 306 AddressList address(session_->connection()->peer_address()); |
307 if (factory_->OnResolution(session_key_, address)) { | 307 if (factory_->OnResolution(server_id_, address)) { |
308 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); | 308 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); |
309 session_ = NULL; | 309 session_ = NULL; |
310 return OK; | 310 return OK; |
311 } | 311 } |
312 | 312 |
313 factory_->ActivateSession(session_key_, session_); | 313 factory_->ActivateSession(server_id_, session_); |
314 | 314 |
315 return OK; | 315 return OK; |
316 } | 316 } |
317 | 317 |
318 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) | 318 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) |
319 : factory_(factory) {} | 319 : factory_(factory) {} |
320 | 320 |
321 QuicStreamRequest::~QuicStreamRequest() { | 321 QuicStreamRequest::~QuicStreamRequest() { |
322 if (factory_ && !callback_.is_null()) | 322 if (factory_ && !callback_.is_null()) |
323 factory_->CancelRequest(this); | 323 factory_->CancelRequest(this); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 STLDeleteElements(&all_sessions_); | 410 STLDeleteElements(&all_sessions_); |
411 STLDeleteValues(&active_jobs_); | 411 STLDeleteValues(&active_jobs_); |
412 } | 412 } |
413 | 413 |
414 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, | 414 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, |
415 bool is_https, | 415 bool is_https, |
416 PrivacyMode privacy_mode, | 416 PrivacyMode privacy_mode, |
417 base::StringPiece method, | 417 base::StringPiece method, |
418 const BoundNetLog& net_log, | 418 const BoundNetLog& net_log, |
419 QuicStreamRequest* request) { | 419 QuicStreamRequest* request) { |
420 QuicSessionKey session_key(host_port_pair, is_https, privacy_mode); | 420 QuicServerId server_id(host_port_pair, is_https, privacy_mode); |
421 if (HasActiveSession(session_key)) { | 421 if (HasActiveSession(server_id)) { |
422 request->set_stream(CreateIfSessionExists(session_key, net_log)); | 422 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
423 return OK; | 423 return OK; |
424 } | 424 } |
425 | 425 |
426 if (HasActiveJob(session_key)) { | 426 if (HasActiveJob(server_id)) { |
427 Job* job = active_jobs_[session_key]; | 427 Job* job = active_jobs_[server_id]; |
428 active_requests_[request] = job; | 428 active_requests_[request] = job; |
429 job_requests_map_[job].insert(request); | 429 job_requests_map_[job].insert(request); |
430 return ERR_IO_PENDING; | 430 return ERR_IO_PENDING; |
431 } | 431 } |
432 | 432 |
433 QuicServerInfo* quic_server_info = NULL; | 433 QuicServerInfo* quic_server_info = NULL; |
434 if (quic_server_info_factory_) { | 434 if (quic_server_info_factory_) { |
435 QuicCryptoClientConfig::CachedState* cached = | 435 QuicCryptoClientConfig::CachedState* cached = |
436 crypto_config_.LookupOrCreate(session_key); | 436 crypto_config_.LookupOrCreate(server_id); |
437 DCHECK(cached); | 437 DCHECK(cached); |
438 if (cached->IsEmpty()) { | 438 if (cached->IsEmpty()) { |
439 quic_server_info = quic_server_info_factory_->GetForServer(session_key); | 439 quic_server_info = quic_server_info_factory_->GetForServer(server_id); |
440 } | 440 } |
441 } | 441 } |
442 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 442 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, |
443 privacy_mode, method, quic_server_info, net_log)); | 443 privacy_mode, method, quic_server_info, net_log)); |
444 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 444 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
445 base::Unretained(this), job.get())); | 445 base::Unretained(this), job.get())); |
446 | 446 |
447 if (rv == ERR_IO_PENDING) { | 447 if (rv == ERR_IO_PENDING) { |
448 active_requests_[request] = job.get(); | 448 active_requests_[request] = job.get(); |
449 job_requests_map_[job.get()].insert(request); | 449 job_requests_map_[job.get()].insert(request); |
450 active_jobs_[session_key] = job.release(); | 450 active_jobs_[server_id] = job.release(); |
451 } | 451 } |
452 if (rv == OK) { | 452 if (rv == OK) { |
453 DCHECK(HasActiveSession(session_key)); | 453 DCHECK(HasActiveSession(server_id)); |
454 request->set_stream(CreateIfSessionExists(session_key, net_log)); | 454 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
455 } | 455 } |
456 return rv; | 456 return rv; |
457 } | 457 } |
458 | 458 |
459 bool QuicStreamFactory::OnResolution( | 459 bool QuicStreamFactory::OnResolution( |
460 const QuicSessionKey& session_key, | 460 const QuicServerId& server_id, |
461 const AddressList& address_list) { | 461 const AddressList& address_list) { |
462 DCHECK(!HasActiveSession(session_key)); | 462 DCHECK(!HasActiveSession(server_id)); |
463 for (size_t i = 0; i < address_list.size(); ++i) { | 463 for (size_t i = 0; i < address_list.size(); ++i) { |
464 const IPEndPoint& address = address_list[i]; | 464 const IPEndPoint& address = address_list[i]; |
465 const IpAliasKey ip_alias_key(address, session_key.is_https()); | 465 const IpAliasKey ip_alias_key(address, server_id.is_https()); |
466 if (!ContainsKey(ip_aliases_, ip_alias_key)) | 466 if (!ContainsKey(ip_aliases_, ip_alias_key)) |
467 continue; | 467 continue; |
468 | 468 |
469 const SessionSet& sessions = ip_aliases_[ip_alias_key]; | 469 const SessionSet& sessions = ip_aliases_[ip_alias_key]; |
470 for (SessionSet::const_iterator i = sessions.begin(); | 470 for (SessionSet::const_iterator i = sessions.begin(); |
471 i != sessions.end(); ++i) { | 471 i != sessions.end(); ++i) { |
472 QuicClientSession* session = *i; | 472 QuicClientSession* session = *i; |
473 if (!session->CanPool(session_key.host())) | 473 if (!session->CanPool(server_id.host())) |
474 continue; | 474 continue; |
475 active_sessions_[session_key] = session; | 475 active_sessions_[server_id] = session; |
476 session_aliases_[session].insert(session_key); | 476 session_aliases_[session].insert(server_id); |
477 return true; | 477 return true; |
478 } | 478 } |
479 } | 479 } |
480 return false; | 480 return false; |
481 } | 481 } |
482 | 482 |
483 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { | 483 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { |
484 if (rv == OK) { | 484 if (rv == OK) { |
485 require_confirmation_ = false; | 485 require_confirmation_ = false; |
486 | 486 |
487 // Create all the streams, but do not notify them yet. | 487 // Create all the streams, but do not notify them yet. |
488 for (RequestSet::iterator it = job_requests_map_[job].begin(); | 488 for (RequestSet::iterator it = job_requests_map_[job].begin(); |
489 it != job_requests_map_[job].end() ; ++it) { | 489 it != job_requests_map_[job].end() ; ++it) { |
490 DCHECK(HasActiveSession(job->session_key())); | 490 DCHECK(HasActiveSession(job->server_id())); |
491 (*it)->set_stream(CreateIfSessionExists(job->session_key(), | 491 (*it)->set_stream(CreateIfSessionExists(job->server_id(), |
492 (*it)->net_log())); | 492 (*it)->net_log())); |
493 } | 493 } |
494 } | 494 } |
495 while (!job_requests_map_[job].empty()) { | 495 while (!job_requests_map_[job].empty()) { |
496 RequestSet::iterator it = job_requests_map_[job].begin(); | 496 RequestSet::iterator it = job_requests_map_[job].begin(); |
497 QuicStreamRequest* request = *it; | 497 QuicStreamRequest* request = *it; |
498 job_requests_map_[job].erase(it); | 498 job_requests_map_[job].erase(it); |
499 active_requests_.erase(request); | 499 active_requests_.erase(request); |
500 // Even though we're invoking callbacks here, we don't need to worry | 500 // Even though we're invoking callbacks here, we don't need to worry |
501 // about |this| being deleted, because the factory is owned by the | 501 // about |this| being deleted, because the factory is owned by the |
502 // profile which can not be deleted via callbacks. | 502 // profile which can not be deleted via callbacks. |
503 request->OnRequestComplete(rv); | 503 request->OnRequestComplete(rv); |
504 } | 504 } |
505 active_jobs_.erase(job->session_key()); | 505 active_jobs_.erase(job->server_id()); |
506 job_requests_map_.erase(job); | 506 job_requests_map_.erase(job); |
507 delete job; | 507 delete job; |
508 return; | 508 return; |
509 } | 509 } |
510 | 510 |
511 // Returns a newly created QuicHttpStream owned by the caller, if a | 511 // Returns a newly created QuicHttpStream owned by the caller, if a |
512 // matching session already exists. Returns NULL otherwise. | 512 // matching session already exists. Returns NULL otherwise. |
513 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( | 513 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( |
514 const QuicSessionKey& session_key, | 514 const QuicServerId& server_id, |
515 const BoundNetLog& net_log) { | 515 const BoundNetLog& net_log) { |
516 if (!HasActiveSession(session_key)) { | 516 if (!HasActiveSession(server_id)) { |
517 DVLOG(1) << "No active session"; | 517 DVLOG(1) << "No active session"; |
518 return scoped_ptr<QuicHttpStream>(); | 518 return scoped_ptr<QuicHttpStream>(); |
519 } | 519 } |
520 | 520 |
521 QuicClientSession* session = active_sessions_[session_key]; | 521 QuicClientSession* session = active_sessions_[server_id]; |
522 DCHECK(session); | 522 DCHECK(session); |
523 return scoped_ptr<QuicHttpStream>( | 523 return scoped_ptr<QuicHttpStream>( |
524 new QuicHttpStream(session->GetWeakPtr())); | 524 new QuicHttpStream(session->GetWeakPtr())); |
525 } | 525 } |
526 | 526 |
527 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { | 527 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { |
528 } | 528 } |
529 | 529 |
530 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { | 530 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { |
531 const QuicConnectionStats& stats = session->connection()->GetStats(); | 531 const QuicConnectionStats& stats = session->connection()->GetStats(); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 DCHECK_NE(initial_size, all_sessions_.size()); | 612 DCHECK_NE(initial_size, all_sessions_.size()); |
613 } | 613 } |
614 DCHECK(all_sessions_.empty()); | 614 DCHECK(all_sessions_.empty()); |
615 } | 615 } |
616 | 616 |
617 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { | 617 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { |
618 base::ListValue* list = new base::ListValue(); | 618 base::ListValue* list = new base::ListValue(); |
619 | 619 |
620 for (SessionMap::const_iterator it = active_sessions_.begin(); | 620 for (SessionMap::const_iterator it = active_sessions_.begin(); |
621 it != active_sessions_.end(); ++it) { | 621 it != active_sessions_.end(); ++it) { |
622 const QuicSessionKey& session_key = it->first; | 622 const QuicServerId& server_id = it->first; |
623 QuicClientSession* session = it->second; | 623 QuicClientSession* session = it->second; |
624 const AliasSet& aliases = session_aliases_.find(session)->second; | 624 const AliasSet& aliases = session_aliases_.find(session)->second; |
625 // Only add a session to the list once. | 625 // Only add a session to the list once. |
626 if (session_key == *aliases.begin()) { | 626 if (server_id == *aliases.begin()) { |
627 std::set<HostPortPair> hosts; | 627 std::set<HostPortPair> hosts; |
628 for (AliasSet::const_iterator alias_it = aliases.begin(); | 628 for (AliasSet::const_iterator alias_it = aliases.begin(); |
629 alias_it != aliases.end(); ++alias_it) { | 629 alias_it != aliases.end(); ++alias_it) { |
630 hosts.insert(alias_it->host_port_pair()); | 630 hosts.insert(alias_it->host_port_pair()); |
631 } | 631 } |
632 list->Append(session->GetInfoAsValue(hosts)); | 632 list->Append(session->GetInfoAsValue(hosts)); |
633 } | 633 } |
634 } | 634 } |
635 return list; | 635 return list; |
636 } | 636 } |
(...skipping 14 matching lines...) Expand all Loading... |
651 // | 651 // |
652 // We should not flush the sessions if we added trust to a cert. | 652 // We should not flush the sessions if we added trust to a cert. |
653 // | 653 // |
654 // Since the OnCACertChanged method doesn't tell us what | 654 // Since the OnCACertChanged method doesn't tell us what |
655 // kind of change it is, we have to flush the socket | 655 // kind of change it is, we have to flush the socket |
656 // pools to be safe. | 656 // pools to be safe. |
657 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 657 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
658 } | 658 } |
659 | 659 |
660 bool QuicStreamFactory::HasActiveSession( | 660 bool QuicStreamFactory::HasActiveSession( |
661 const QuicSessionKey& session_key) const { | 661 const QuicServerId& server_id) const { |
662 return ContainsKey(active_sessions_, session_key); | 662 return ContainsKey(active_sessions_, server_id); |
663 } | 663 } |
664 | 664 |
665 int QuicStreamFactory::CreateSession( | 665 int QuicStreamFactory::CreateSession( |
666 const QuicSessionKey& session_key, | 666 const QuicServerId& server_id, |
667 scoped_ptr<QuicServerInfo> server_info, | 667 scoped_ptr<QuicServerInfo> server_info, |
668 const AddressList& address_list, | 668 const AddressList& address_list, |
669 const BoundNetLog& net_log, | 669 const BoundNetLog& net_log, |
670 QuicClientSession** session) { | 670 QuicClientSession** session) { |
671 bool enable_port_selection = enable_port_selection_; | 671 bool enable_port_selection = enable_port_selection_; |
672 if (enable_port_selection && | 672 if (enable_port_selection && |
673 ContainsKey(gone_away_aliases_, session_key)) { | 673 ContainsKey(gone_away_aliases_, server_id)) { |
674 // Disable port selection when the server is going away. | 674 // Disable port selection when the server is going away. |
675 // There is no point in trying to return to the same server, if | 675 // There is no point in trying to return to the same server, if |
676 // that server is no longer handling requests. | 676 // that server is no longer handling requests. |
677 enable_port_selection = false; | 677 enable_port_selection = false; |
678 gone_away_aliases_.erase(session_key); | 678 gone_away_aliases_.erase(server_id); |
679 } | 679 } |
680 | 680 |
681 QuicConnectionId connection_id = random_generator_->RandUint64(); | 681 QuicConnectionId connection_id = random_generator_->RandUint64(); |
682 IPEndPoint addr = *address_list.begin(); | 682 IPEndPoint addr = *address_list.begin(); |
683 scoped_refptr<PortSuggester> port_suggester = | 683 scoped_refptr<PortSuggester> port_suggester = |
684 new PortSuggester(session_key.host_port_pair(), port_seed_); | 684 new PortSuggester(server_id.host_port_pair(), port_seed_); |
685 DatagramSocket::BindType bind_type = enable_port_selection ? | 685 DatagramSocket::BindType bind_type = enable_port_selection ? |
686 DatagramSocket::RANDOM_BIND : // Use our callback. | 686 DatagramSocket::RANDOM_BIND : // Use our callback. |
687 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 687 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
688 scoped_ptr<DatagramClientSocket> socket( | 688 scoped_ptr<DatagramClientSocket> socket( |
689 client_socket_factory_->CreateDatagramClientSocket( | 689 client_socket_factory_->CreateDatagramClientSocket( |
690 bind_type, | 690 bind_type, |
691 base::Bind(&PortSuggester::SuggestPort, port_suggester), | 691 base::Bind(&PortSuggester::SuggestPort, port_suggester), |
692 net_log.net_log(), net_log.source())); | 692 net_log.net_log(), net_log.source())); |
693 int rv = socket->Connect(addr); | 693 int rv = socket->Connect(addr); |
694 if (rv != OK) { | 694 if (rv != OK) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 base::MessageLoop::current()->message_loop_proxy().get(), | 728 base::MessageLoop::current()->message_loop_proxy().get(), |
729 clock_.get(), random_generator_)); | 729 clock_.get(), random_generator_)); |
730 } | 730 } |
731 | 731 |
732 QuicConnection* connection = | 732 QuicConnection* connection = |
733 new QuicConnection(connection_id, addr, helper_.get(), writer.get(), | 733 new QuicConnection(connection_id, addr, helper_.get(), writer.get(), |
734 false, supported_versions_, kInitialReceiveWindowSize); | 734 false, supported_versions_, kInitialReceiveWindowSize); |
735 writer->SetConnection(connection); | 735 writer->SetConnection(connection); |
736 connection->options()->max_packet_length = max_packet_length_; | 736 connection->options()->max_packet_length = max_packet_length_; |
737 | 737 |
738 InitializeCachedState(session_key, server_info); | 738 InitializeCachedState(server_id, server_info); |
739 | 739 |
740 QuicConfig config = config_; | 740 QuicConfig config = config_; |
741 if (http_server_properties_) { | 741 if (http_server_properties_) { |
742 const HttpServerProperties::NetworkStats* stats = | 742 const HttpServerProperties::NetworkStats* stats = |
743 http_server_properties_->GetServerNetworkStats( | 743 http_server_properties_->GetServerNetworkStats( |
744 session_key.host_port_pair()); | 744 server_id.host_port_pair()); |
745 if (stats != NULL) { | 745 if (stats != NULL) { |
746 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), | 746 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), |
747 stats->rtt.InMicroseconds()); | 747 stats->rtt.InMicroseconds()); |
748 } | 748 } |
749 } | 749 } |
750 | 750 |
751 *session = new QuicClientSession( | 751 *session = new QuicClientSession( |
752 connection, socket.Pass(), writer.Pass(), this, | 752 connection, socket.Pass(), writer.Pass(), this, |
753 quic_crypto_client_stream_factory_, server_info.Pass(), session_key, | 753 quic_crypto_client_stream_factory_, server_info.Pass(), server_id, |
754 config, &crypto_config_, net_log.net_log()); | 754 config, &crypto_config_, net_log.net_log()); |
755 all_sessions_.insert(*session); // owning pointer | 755 all_sessions_.insert(*session); // owning pointer |
756 return OK; | 756 return OK; |
757 } | 757 } |
758 | 758 |
759 bool QuicStreamFactory::HasActiveJob(const QuicSessionKey& key) const { | 759 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { |
760 return ContainsKey(active_jobs_, key); | 760 return ContainsKey(active_jobs_, key); |
761 } | 761 } |
762 | 762 |
763 void QuicStreamFactory::ActivateSession( | 763 void QuicStreamFactory::ActivateSession( |
764 const QuicSessionKey& session_key, | 764 const QuicServerId& server_id, |
765 QuicClientSession* session) { | 765 QuicClientSession* session) { |
766 DCHECK(!HasActiveSession(session_key)); | 766 DCHECK(!HasActiveSession(server_id)); |
767 active_sessions_[session_key] = session; | 767 active_sessions_[server_id] = session; |
768 session_aliases_[session].insert(session_key); | 768 session_aliases_[session].insert(server_id); |
769 const IpAliasKey ip_alias_key(session->connection()->peer_address(), | 769 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
770 session_key.is_https()); | 770 server_id.is_https()); |
771 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); | 771 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); |
772 ip_aliases_[ip_alias_key].insert(session); | 772 ip_aliases_[ip_alias_key].insert(session); |
773 } | 773 } |
774 | 774 |
775 void QuicStreamFactory::InitializeCachedState( | 775 void QuicStreamFactory::InitializeCachedState( |
776 const QuicSessionKey& session_key, | 776 const QuicServerId& server_id, |
777 const scoped_ptr<QuicServerInfo>& server_info) { | 777 const scoped_ptr<QuicServerInfo>& server_info) { |
778 if (!server_info) | 778 if (!server_info) |
779 return; | 779 return; |
780 | 780 |
781 QuicCryptoClientConfig::CachedState* cached = | 781 QuicCryptoClientConfig::CachedState* cached = |
782 crypto_config_.LookupOrCreate(session_key); | 782 crypto_config_.LookupOrCreate(server_id); |
783 if (!cached->IsEmpty()) | 783 if (!cached->IsEmpty()) |
784 return; | 784 return; |
785 | 785 |
786 if (!cached->Initialize(server_info->state().server_config, | 786 if (!cached->Initialize(server_info->state().server_config, |
787 server_info->state().source_address_token, | 787 server_info->state().source_address_token, |
788 server_info->state().certs, | 788 server_info->state().certs, |
789 server_info->state().server_config_sig, | 789 server_info->state().server_config_sig, |
790 clock_->WallNow())) | 790 clock_->WallNow())) |
791 return; | 791 return; |
792 | 792 |
793 if (!session_key.is_https()) { | 793 if (!server_id.is_https()) { |
794 // Don't check the certificates for insecure QUIC. | 794 // Don't check the certificates for insecure QUIC. |
795 cached->SetProofValid(); | 795 cached->SetProofValid(); |
796 } | 796 } |
797 } | 797 } |
798 | 798 |
799 void QuicStreamFactory::ExpireBrokenAlternateProtocolMappings() { | 799 void QuicStreamFactory::ExpireBrokenAlternateProtocolMappings() { |
800 base::TimeTicks now = base::TimeTicks::Now(); | 800 base::TimeTicks now = base::TimeTicks::Now(); |
801 while (!broken_alternate_protocol_list_.empty()) { | 801 while (!broken_alternate_protocol_list_.empty()) { |
802 BrokenAlternateProtocolEntry entry = | 802 BrokenAlternateProtocolEntry entry = |
803 broken_alternate_protocol_list_.front(); | 803 broken_alternate_protocol_list_.front(); |
(...skipping 15 matching lines...) Expand all Loading... |
819 base::TimeTicks when = broken_alternate_protocol_list_.front().when; | 819 base::TimeTicks when = broken_alternate_protocol_list_.front().when; |
820 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 820 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
821 base::MessageLoop::current()->PostDelayedTask( | 821 base::MessageLoop::current()->PostDelayedTask( |
822 FROM_HERE, | 822 FROM_HERE, |
823 base::Bind(&QuicStreamFactory::ExpireBrokenAlternateProtocolMappings, | 823 base::Bind(&QuicStreamFactory::ExpireBrokenAlternateProtocolMappings, |
824 weak_factory_.GetWeakPtr()), | 824 weak_factory_.GetWeakPtr()), |
825 delay); | 825 delay); |
826 } | 826 } |
827 | 827 |
828 } // namespace net | 828 } // namespace net |
OLD | NEW |