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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 CREATION_ERROR_CONNECTING_SOCKET, | 50 CREATION_ERROR_CONNECTING_SOCKET, |
51 CREATION_ERROR_SETTING_RECEIVE_BUFFER, | 51 CREATION_ERROR_SETTING_RECEIVE_BUFFER, |
52 CREATION_ERROR_SETTING_SEND_BUFFER, | 52 CREATION_ERROR_SETTING_SEND_BUFFER, |
53 CREATION_ERROR_MAX | 53 CREATION_ERROR_MAX |
54 }; | 54 }; |
55 | 55 |
56 // The initial receive window size for both streams and sessions. | 56 // The initial receive window size for both streams and sessions. |
57 const int32 kInitialReceiveWindowSize = 10 * 1024 * 1024; // 10MB | 57 const int32 kInitialReceiveWindowSize = 10 * 1024 * 1024; // 10MB |
58 | 58 |
59 void HistogramCreateSessionFailure(enum CreateSessionFailure error) { | 59 void HistogramCreateSessionFailure(enum CreateSessionFailure error) { |
60 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error, | 60 UMA_HISTOGRAM_ENUMERATION( |
61 CREATION_ERROR_MAX); | 61 "Net.QuicSession.CreationError", error, CREATION_ERROR_MAX); |
62 } | 62 } |
63 | 63 |
64 bool IsEcdsaSupported() { | 64 bool IsEcdsaSupported() { |
65 #if defined(OS_WIN) | 65 #if defined(OS_WIN) |
66 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 66 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
67 return false; | 67 return false; |
68 #endif | 68 #endif |
69 | 69 |
70 return true; | 70 return true; |
71 } | 71 } |
72 | 72 |
73 } // namespace | 73 } // namespace |
74 | 74 |
75 QuicStreamFactory::IpAliasKey::IpAliasKey() {} | 75 QuicStreamFactory::IpAliasKey::IpAliasKey() { |
| 76 } |
76 | 77 |
77 QuicStreamFactory::IpAliasKey::IpAliasKey(IPEndPoint ip_endpoint, | 78 QuicStreamFactory::IpAliasKey::IpAliasKey(IPEndPoint ip_endpoint, bool is_https) |
78 bool is_https) | 79 : ip_endpoint(ip_endpoint), is_https(is_https) { |
79 : ip_endpoint(ip_endpoint), | 80 } |
80 is_https(is_https) {} | |
81 | 81 |
82 QuicStreamFactory::IpAliasKey::~IpAliasKey() {} | 82 QuicStreamFactory::IpAliasKey::~IpAliasKey() { |
| 83 } |
83 | 84 |
84 bool QuicStreamFactory::IpAliasKey::operator<( | 85 bool QuicStreamFactory::IpAliasKey::operator<( |
85 const QuicStreamFactory::IpAliasKey& other) const { | 86 const QuicStreamFactory::IpAliasKey& other) const { |
86 if (!(ip_endpoint == other.ip_endpoint)) { | 87 if (!(ip_endpoint == other.ip_endpoint)) { |
87 return ip_endpoint < other.ip_endpoint; | 88 return ip_endpoint < other.ip_endpoint; |
88 } | 89 } |
89 return is_https < other.is_https; | 90 return is_https < other.is_https; |
90 } | 91 } |
91 | 92 |
92 bool QuicStreamFactory::IpAliasKey::operator==( | 93 bool QuicStreamFactory::IpAliasKey::operator==( |
93 const QuicStreamFactory::IpAliasKey& other) const { | 94 const QuicStreamFactory::IpAliasKey& other) const { |
94 return is_https == other.is_https && | 95 return is_https == other.is_https && ip_endpoint == other.ip_endpoint; |
95 ip_endpoint == other.ip_endpoint; | |
96 }; | 96 }; |
97 | 97 |
98 // Responsible for creating a new QUIC session to the specified server, and | 98 // Responsible for creating a new QUIC session to the specified server, and |
99 // for notifying any associated requests when complete. | 99 // for notifying any associated requests when complete. |
100 class QuicStreamFactory::Job { | 100 class QuicStreamFactory::Job { |
101 public: | 101 public: |
102 Job(QuicStreamFactory* factory, | 102 Job(QuicStreamFactory* factory, |
103 HostResolver* host_resolver, | 103 HostResolver* host_resolver, |
104 const HostPortPair& host_port_pair, | 104 const HostPortPair& host_port_pair, |
105 bool is_https, | 105 bool is_https, |
(...skipping 10 matching lines...) Expand all Loading... |
116 int DoLoop(int rv); | 116 int DoLoop(int rv); |
117 int DoResolveHost(); | 117 int DoResolveHost(); |
118 int DoResolveHostComplete(int rv); | 118 int DoResolveHostComplete(int rv); |
119 int DoLoadServerInfo(); | 119 int DoLoadServerInfo(); |
120 int DoLoadServerInfoComplete(int rv); | 120 int DoLoadServerInfoComplete(int rv); |
121 int DoConnect(); | 121 int DoConnect(); |
122 int DoConnectComplete(int rv); | 122 int DoConnectComplete(int rv); |
123 | 123 |
124 void OnIOComplete(int rv); | 124 void OnIOComplete(int rv); |
125 | 125 |
126 CompletionCallback callback() { | 126 CompletionCallback callback() { return callback_; } |
127 return callback_; | |
128 } | |
129 | 127 |
130 const QuicServerId server_id() const { | 128 const QuicServerId server_id() const { return server_id_; } |
131 return server_id_; | |
132 } | |
133 | 129 |
134 private: | 130 private: |
135 enum IoState { | 131 enum IoState { |
136 STATE_NONE, | 132 STATE_NONE, |
137 STATE_RESOLVE_HOST, | 133 STATE_RESOLVE_HOST, |
138 STATE_RESOLVE_HOST_COMPLETE, | 134 STATE_RESOLVE_HOST_COMPLETE, |
139 STATE_LOAD_SERVER_INFO, | 135 STATE_LOAD_SERVER_INFO, |
140 STATE_LOAD_SERVER_INFO_COMPLETE, | 136 STATE_LOAD_SERVER_INFO_COMPLETE, |
141 STATE_CONNECT, | 137 STATE_CONNECT, |
142 STATE_CONNECT_COMPLETE, | 138 STATE_CONNECT_COMPLETE, |
(...skipping 26 matching lines...) Expand all Loading... |
169 const BoundNetLog& net_log) | 165 const BoundNetLog& net_log) |
170 : factory_(factory), | 166 : factory_(factory), |
171 host_resolver_(host_resolver), | 167 host_resolver_(host_resolver), |
172 server_id_(host_port_pair, is_https, privacy_mode), | 168 server_id_(host_port_pair, is_https, privacy_mode), |
173 is_post_(method == "POST"), | 169 is_post_(method == "POST"), |
174 was_alternate_protocol_recently_broken_( | 170 was_alternate_protocol_recently_broken_( |
175 was_alternate_protocol_recently_broken), | 171 was_alternate_protocol_recently_broken), |
176 server_info_(server_info), | 172 server_info_(server_info), |
177 net_log_(net_log), | 173 net_log_(net_log), |
178 session_(NULL), | 174 session_(NULL), |
179 weak_factory_(this) {} | 175 weak_factory_(this) { |
| 176 } |
180 | 177 |
181 QuicStreamFactory::Job::~Job() { | 178 QuicStreamFactory::Job::~Job() { |
182 } | 179 } |
183 | 180 |
184 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 181 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
185 io_state_ = STATE_RESOLVE_HOST; | 182 io_state_ = STATE_RESOLVE_HOST; |
186 int rv = DoLoop(OK); | 183 int rv = DoLoop(OK); |
187 if (rv == ERR_IO_PENDING) | 184 if (rv == ERR_IO_PENDING) |
188 callback_ = callback; | 185 callback_ = callback; |
189 | 186 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 io_state_ = STATE_LOAD_SERVER_INFO; | 261 io_state_ = STATE_LOAD_SERVER_INFO; |
265 return OK; | 262 return OK; |
266 } | 263 } |
267 | 264 |
268 int QuicStreamFactory::Job::DoLoadServerInfo() { | 265 int QuicStreamFactory::Job::DoLoadServerInfo() { |
269 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; | 266 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; |
270 | 267 |
271 if (!server_info_) | 268 if (!server_info_) |
272 return OK; | 269 return OK; |
273 | 270 |
274 return server_info_->WaitForDataReady( | 271 return server_info_->WaitForDataReady(base::Bind( |
275 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 272 &QuicStreamFactory::Job::OnIOComplete, weak_factory_.GetWeakPtr())); |
276 weak_factory_.GetWeakPtr())); | |
277 } | 273 } |
278 | 274 |
279 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { | 275 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { |
280 if (server_info_) { | 276 if (server_info_) { |
281 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheReadTime", | 277 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheReadTime", |
282 base::TimeTicks::Now() - disk_cache_load_start_time_); | 278 base::TimeTicks::Now() - disk_cache_load_start_time_); |
283 } | 279 } |
284 | 280 |
285 if (rv != OK) { | 281 if (rv != OK) { |
286 server_info_.reset(); | 282 server_info_.reset(); |
287 } | 283 } |
288 | 284 |
289 io_state_ = STATE_CONNECT; | 285 io_state_ = STATE_CONNECT; |
290 return OK; | 286 return OK; |
291 } | 287 } |
292 | 288 |
293 int QuicStreamFactory::Job::DoConnect() { | 289 int QuicStreamFactory::Job::DoConnect() { |
294 io_state_ = STATE_CONNECT_COMPLETE; | 290 io_state_ = STATE_CONNECT_COMPLETE; |
295 | 291 |
296 int rv = factory_->CreateSession(server_id_, server_info_.Pass(), | 292 int rv = factory_->CreateSession( |
297 address_list_, net_log_, &session_); | 293 server_id_, server_info_.Pass(), address_list_, net_log_, &session_); |
298 if (rv != OK) { | 294 if (rv != OK) { |
299 DCHECK(rv != ERR_IO_PENDING); | 295 DCHECK(rv != ERR_IO_PENDING); |
300 DCHECK(!session_); | 296 DCHECK(!session_); |
301 return rv; | 297 return rv; |
302 } | 298 } |
303 | 299 |
304 session_->StartReading(); | 300 session_->StartReading(); |
305 if (!session_->connection()->connected()) { | 301 if (!session_->connection()->connected()) { |
306 return ERR_QUIC_PROTOCOL_ERROR; | 302 return ERR_QUIC_PROTOCOL_ERROR; |
307 } | 303 } |
308 bool require_confirmation = | 304 bool require_confirmation = factory_->require_confirmation() || |
309 factory_->require_confirmation() || server_id_.is_https() || is_post_ || | 305 server_id_.is_https() || is_post_ || |
310 was_alternate_protocol_recently_broken_; | 306 was_alternate_protocol_recently_broken_; |
311 rv = session_->CryptoConnect( | 307 rv = session_->CryptoConnect(require_confirmation, |
312 require_confirmation, | 308 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
313 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 309 base::Unretained(this))); |
314 base::Unretained(this))); | |
315 return rv; | 310 return rv; |
316 } | 311 } |
317 | 312 |
318 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 313 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
319 if (rv != OK) | 314 if (rv != OK) |
320 return rv; | 315 return rv; |
321 | 316 |
322 DCHECK(!factory_->HasActiveSession(server_id_)); | 317 DCHECK(!factory_->HasActiveSession(server_id_)); |
323 // There may well now be an active session for this IP. If so, use the | 318 // There may well now be an active session for this IP. If so, use the |
324 // existing session instead. | 319 // existing session instead. |
325 AddressList address(session_->connection()->peer_address()); | 320 AddressList address(session_->connection()->peer_address()); |
326 if (factory_->OnResolution(server_id_, address)) { | 321 if (factory_->OnResolution(server_id_, address)) { |
327 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); | 322 session_->connection()->SendConnectionClose(QUIC_NO_ERROR); |
328 session_ = NULL; | 323 session_ = NULL; |
329 return OK; | 324 return OK; |
330 } | 325 } |
331 | 326 |
332 factory_->ActivateSession(server_id_, session_); | 327 factory_->ActivateSession(server_id_, session_); |
333 | 328 |
334 return OK; | 329 return OK; |
335 } | 330 } |
336 | 331 |
337 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) | 332 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) |
338 : factory_(factory) {} | 333 : factory_(factory) { |
| 334 } |
339 | 335 |
340 QuicStreamRequest::~QuicStreamRequest() { | 336 QuicStreamRequest::~QuicStreamRequest() { |
341 if (factory_ && !callback_.is_null()) | 337 if (factory_ && !callback_.is_null()) |
342 factory_->CancelRequest(this); | 338 factory_->CancelRequest(this); |
343 } | 339 } |
344 | 340 |
345 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, | 341 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, |
346 bool is_https, | 342 bool is_https, |
347 PrivacyMode privacy_mode, | 343 PrivacyMode privacy_mode, |
348 base::StringPiece method, | 344 base::StringPiece method, |
349 const BoundNetLog& net_log, | 345 const BoundNetLog& net_log, |
350 const CompletionCallback& callback) { | 346 const CompletionCallback& callback) { |
351 DCHECK(!stream_); | 347 DCHECK(!stream_); |
352 DCHECK(callback_.is_null()); | 348 DCHECK(callback_.is_null()); |
353 DCHECK(factory_); | 349 DCHECK(factory_); |
354 int rv = factory_->Create(host_port_pair, is_https, privacy_mode, method, | 350 int rv = factory_->Create( |
355 net_log, this); | 351 host_port_pair, is_https, privacy_mode, method, net_log, this); |
356 if (rv == ERR_IO_PENDING) { | 352 if (rv == ERR_IO_PENDING) { |
357 host_port_pair_ = host_port_pair; | 353 host_port_pair_ = host_port_pair; |
358 is_https_ = is_https; | 354 is_https_ = is_https; |
359 net_log_ = net_log; | 355 net_log_ = net_log; |
360 callback_ = callback; | 356 callback_ = callback; |
361 } else { | 357 } else { |
362 factory_ = NULL; | 358 factory_ = NULL; |
363 } | 359 } |
364 if (rv == OK) | 360 if (rv == OK) |
365 DCHECK(stream_); | 361 DCHECK(stream_); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 max_packet_length_(max_packet_length), | 402 max_packet_length_(max_packet_length), |
407 supported_versions_(supported_versions), | 403 supported_versions_(supported_versions), |
408 enable_port_selection_(enable_port_selection), | 404 enable_port_selection_(enable_port_selection), |
409 enable_pacing_(enable_pacing), | 405 enable_pacing_(enable_pacing), |
410 port_seed_(random_generator_->RandUint64()), | 406 port_seed_(random_generator_->RandUint64()), |
411 weak_factory_(this) { | 407 weak_factory_(this) { |
412 config_.SetDefaults(); | 408 config_.SetDefaults(); |
413 config_.EnablePacing(enable_pacing_); | 409 config_.EnablePacing(enable_pacing_); |
414 if (enable_time_based_loss_detection) | 410 if (enable_time_based_loss_detection) |
415 config_.SetLossDetectionToSend(kTIME); | 411 config_.SetLossDetectionToSend(kTIME); |
416 config_.set_idle_connection_state_lifetime( | 412 config_.set_idle_connection_state_lifetime(QuicTime::Delta::FromSeconds(30), |
417 QuicTime::Delta::FromSeconds(30), | 413 QuicTime::Delta::FromSeconds(30)); |
418 QuicTime::Delta::FromSeconds(30)); | |
419 | 414 |
420 crypto_config_.SetDefaults(); | 415 crypto_config_.SetDefaults(); |
421 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); | 416 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); |
422 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); | 417 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); |
423 crypto_config_.SetProofVerifier(new ProofVerifierChromium(cert_verifier)); | 418 crypto_config_.SetProofVerifier(new ProofVerifierChromium(cert_verifier)); |
424 base::CPU cpu; | 419 base::CPU cpu; |
425 if (cpu.has_aesni() && cpu.has_avx()) | 420 if (cpu.has_aesni() && cpu.has_avx()) |
426 crypto_config_.PreferAesGcm(); | 421 crypto_config_.PreferAesGcm(); |
427 if (!IsEcdsaSupported()) | 422 if (!IsEcdsaSupported()) |
428 crypto_config_.DisableEcdsa(); | 423 crypto_config_.DisableEcdsa(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 crypto_config_.LookupOrCreate(server_id); | 457 crypto_config_.LookupOrCreate(server_id); |
463 DCHECK(cached); | 458 DCHECK(cached); |
464 if (cached->IsEmpty()) { | 459 if (cached->IsEmpty()) { |
465 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | 460 quic_server_info = quic_server_info_factory_->GetForServer(server_id); |
466 } | 461 } |
467 } | 462 } |
468 bool was_alternate_protocol_recently_broken = | 463 bool was_alternate_protocol_recently_broken = |
469 http_server_properties_ && | 464 http_server_properties_ && |
470 http_server_properties_->WasAlternateProtocolRecentlyBroken( | 465 http_server_properties_->WasAlternateProtocolRecentlyBroken( |
471 server_id.host_port_pair()); | 466 server_id.host_port_pair()); |
472 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 467 scoped_ptr<Job> job(new Job(this, |
| 468 host_resolver_, |
| 469 host_port_pair, |
| 470 is_https, |
473 was_alternate_protocol_recently_broken, | 471 was_alternate_protocol_recently_broken, |
474 privacy_mode, method, quic_server_info, net_log)); | 472 privacy_mode, |
475 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 473 method, |
476 base::Unretained(this), job.get())); | 474 quic_server_info, |
| 475 net_log)); |
| 476 int rv = job->Run(base::Bind( |
| 477 &QuicStreamFactory::OnJobComplete, base::Unretained(this), job.get())); |
477 | 478 |
478 if (rv == ERR_IO_PENDING) { | 479 if (rv == ERR_IO_PENDING) { |
479 active_requests_[request] = job.get(); | 480 active_requests_[request] = job.get(); |
480 job_requests_map_[job.get()].insert(request); | 481 job_requests_map_[job.get()].insert(request); |
481 active_jobs_[server_id] = job.release(); | 482 active_jobs_[server_id] = job.release(); |
482 } | 483 } |
483 if (rv == OK) { | 484 if (rv == OK) { |
484 DCHECK(HasActiveSession(server_id)); | 485 DCHECK(HasActiveSession(server_id)); |
485 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 486 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
486 } | 487 } |
487 return rv; | 488 return rv; |
488 } | 489 } |
489 | 490 |
490 bool QuicStreamFactory::OnResolution( | 491 bool QuicStreamFactory::OnResolution(const QuicServerId& server_id, |
491 const QuicServerId& server_id, | 492 const AddressList& address_list) { |
492 const AddressList& address_list) { | |
493 DCHECK(!HasActiveSession(server_id)); | 493 DCHECK(!HasActiveSession(server_id)); |
494 for (size_t i = 0; i < address_list.size(); ++i) { | 494 for (size_t i = 0; i < address_list.size(); ++i) { |
495 const IPEndPoint& address = address_list[i]; | 495 const IPEndPoint& address = address_list[i]; |
496 const IpAliasKey ip_alias_key(address, server_id.is_https()); | 496 const IpAliasKey ip_alias_key(address, server_id.is_https()); |
497 if (!ContainsKey(ip_aliases_, ip_alias_key)) | 497 if (!ContainsKey(ip_aliases_, ip_alias_key)) |
498 continue; | 498 continue; |
499 | 499 |
500 const SessionSet& sessions = ip_aliases_[ip_alias_key]; | 500 const SessionSet& sessions = ip_aliases_[ip_alias_key]; |
501 for (SessionSet::const_iterator i = sessions.begin(); | 501 for (SessionSet::const_iterator i = sessions.begin(); i != sessions.end(); |
502 i != sessions.end(); ++i) { | 502 ++i) { |
503 QuicClientSession* session = *i; | 503 QuicClientSession* session = *i; |
504 if (!session->CanPool(server_id.host())) | 504 if (!session->CanPool(server_id.host())) |
505 continue; | 505 continue; |
506 active_sessions_[server_id] = session; | 506 active_sessions_[server_id] = session; |
507 session_aliases_[session].insert(server_id); | 507 session_aliases_[session].insert(server_id); |
508 return true; | 508 return true; |
509 } | 509 } |
510 } | 510 } |
511 return false; | 511 return false; |
512 } | 512 } |
513 | 513 |
514 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { | 514 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { |
515 if (rv == OK) { | 515 if (rv == OK) { |
516 require_confirmation_ = false; | 516 require_confirmation_ = false; |
517 | 517 |
518 // Create all the streams, but do not notify them yet. | 518 // Create all the streams, but do not notify them yet. |
519 for (RequestSet::iterator it = job_requests_map_[job].begin(); | 519 for (RequestSet::iterator it = job_requests_map_[job].begin(); |
520 it != job_requests_map_[job].end() ; ++it) { | 520 it != job_requests_map_[job].end(); |
| 521 ++it) { |
521 DCHECK(HasActiveSession(job->server_id())); | 522 DCHECK(HasActiveSession(job->server_id())); |
522 (*it)->set_stream(CreateIfSessionExists(job->server_id(), | 523 (*it)->set_stream( |
523 (*it)->net_log())); | 524 CreateIfSessionExists(job->server_id(), (*it)->net_log())); |
524 } | 525 } |
525 } | 526 } |
526 while (!job_requests_map_[job].empty()) { | 527 while (!job_requests_map_[job].empty()) { |
527 RequestSet::iterator it = job_requests_map_[job].begin(); | 528 RequestSet::iterator it = job_requests_map_[job].begin(); |
528 QuicStreamRequest* request = *it; | 529 QuicStreamRequest* request = *it; |
529 job_requests_map_[job].erase(it); | 530 job_requests_map_[job].erase(it); |
530 active_requests_.erase(request); | 531 active_requests_.erase(request); |
531 // Even though we're invoking callbacks here, we don't need to worry | 532 // Even though we're invoking callbacks here, we don't need to worry |
532 // about |this| being deleted, because the factory is owned by the | 533 // about |this| being deleted, because the factory is owned by the |
533 // profile which can not be deleted via callbacks. | 534 // profile which can not be deleted via callbacks. |
(...skipping 10 matching lines...) Expand all Loading... |
544 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( | 545 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( |
545 const QuicServerId& server_id, | 546 const QuicServerId& server_id, |
546 const BoundNetLog& net_log) { | 547 const BoundNetLog& net_log) { |
547 if (!HasActiveSession(server_id)) { | 548 if (!HasActiveSession(server_id)) { |
548 DVLOG(1) << "No active session"; | 549 DVLOG(1) << "No active session"; |
549 return scoped_ptr<QuicHttpStream>(); | 550 return scoped_ptr<QuicHttpStream>(); |
550 } | 551 } |
551 | 552 |
552 QuicClientSession* session = active_sessions_[server_id]; | 553 QuicClientSession* session = active_sessions_[server_id]; |
553 DCHECK(session); | 554 DCHECK(session); |
554 return scoped_ptr<QuicHttpStream>( | 555 return scoped_ptr<QuicHttpStream>(new QuicHttpStream(session->GetWeakPtr())); |
555 new QuicHttpStream(session->GetWeakPtr())); | |
556 } | 556 } |
557 | 557 |
558 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { | 558 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { |
559 } | 559 } |
560 | 560 |
561 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { | 561 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { |
562 const AliasSet& aliases = session_aliases_[session]; | 562 const AliasSet& aliases = session_aliases_[session]; |
563 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); | 563 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); |
564 ++it) { | 564 ++it) { |
565 DCHECK(active_sessions_.count(*it)); | 565 DCHECK(active_sessions_.count(*it)); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 all_sessions_.begin()->first->CloseSessionOnError(error); | 610 all_sessions_.begin()->first->CloseSessionOnError(error); |
611 DCHECK_NE(initial_size, all_sessions_.size()); | 611 DCHECK_NE(initial_size, all_sessions_.size()); |
612 } | 612 } |
613 DCHECK(all_sessions_.empty()); | 613 DCHECK(all_sessions_.empty()); |
614 } | 614 } |
615 | 615 |
616 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { | 616 base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { |
617 base::ListValue* list = new base::ListValue(); | 617 base::ListValue* list = new base::ListValue(); |
618 | 618 |
619 for (SessionMap::const_iterator it = active_sessions_.begin(); | 619 for (SessionMap::const_iterator it = active_sessions_.begin(); |
620 it != active_sessions_.end(); ++it) { | 620 it != active_sessions_.end(); |
| 621 ++it) { |
621 const QuicServerId& server_id = it->first; | 622 const QuicServerId& server_id = it->first; |
622 QuicClientSession* session = it->second; | 623 QuicClientSession* session = it->second; |
623 const AliasSet& aliases = session_aliases_.find(session)->second; | 624 const AliasSet& aliases = session_aliases_.find(session)->second; |
624 // Only add a session to the list once. | 625 // Only add a session to the list once. |
625 if (server_id == *aliases.begin()) { | 626 if (server_id == *aliases.begin()) { |
626 std::set<HostPortPair> hosts; | 627 std::set<HostPortPair> hosts; |
627 for (AliasSet::const_iterator alias_it = aliases.begin(); | 628 for (AliasSet::const_iterator alias_it = aliases.begin(); |
628 alias_it != aliases.end(); ++alias_it) { | 629 alias_it != aliases.end(); |
| 630 ++alias_it) { |
629 hosts.insert(alias_it->host_port_pair()); | 631 hosts.insert(alias_it->host_port_pair()); |
630 } | 632 } |
631 list->Append(session->GetInfoAsValue(hosts)); | 633 list->Append(session->GetInfoAsValue(hosts)); |
632 } | 634 } |
633 } | 635 } |
634 return list; | 636 return list; |
635 } | 637 } |
636 | 638 |
637 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { | 639 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { |
638 crypto_config_.ClearCachedStates(); | 640 crypto_config_.ClearCachedStates(); |
(...skipping 14 matching lines...) Expand all Loading... |
653 // untrusted. | 655 // untrusted. |
654 // | 656 // |
655 // We should not flush the sessions if we added trust to a cert. | 657 // We should not flush the sessions if we added trust to a cert. |
656 // | 658 // |
657 // Since the OnCACertChanged method doesn't tell us what | 659 // Since the OnCACertChanged method doesn't tell us what |
658 // kind of change it is, we have to flush the socket | 660 // kind of change it is, we have to flush the socket |
659 // pools to be safe. | 661 // pools to be safe. |
660 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 662 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
661 } | 663 } |
662 | 664 |
663 bool QuicStreamFactory::HasActiveSession( | 665 bool QuicStreamFactory::HasActiveSession(const QuicServerId& server_id) const { |
664 const QuicServerId& server_id) const { | |
665 return ContainsKey(active_sessions_, server_id); | 666 return ContainsKey(active_sessions_, server_id); |
666 } | 667 } |
667 | 668 |
668 int QuicStreamFactory::CreateSession( | 669 int QuicStreamFactory::CreateSession(const QuicServerId& server_id, |
669 const QuicServerId& server_id, | 670 scoped_ptr<QuicServerInfo> server_info, |
670 scoped_ptr<QuicServerInfo> server_info, | 671 const AddressList& address_list, |
671 const AddressList& address_list, | 672 const BoundNetLog& net_log, |
672 const BoundNetLog& net_log, | 673 QuicClientSession** session) { |
673 QuicClientSession** session) { | |
674 bool enable_port_selection = enable_port_selection_; | 674 bool enable_port_selection = enable_port_selection_; |
675 if (enable_port_selection && | 675 if (enable_port_selection && ContainsKey(gone_away_aliases_, server_id)) { |
676 ContainsKey(gone_away_aliases_, server_id)) { | |
677 // Disable port selection when the server is going away. | 676 // Disable port selection when the server is going away. |
678 // There is no point in trying to return to the same server, if | 677 // There is no point in trying to return to the same server, if |
679 // that server is no longer handling requests. | 678 // that server is no longer handling requests. |
680 enable_port_selection = false; | 679 enable_port_selection = false; |
681 gone_away_aliases_.erase(server_id); | 680 gone_away_aliases_.erase(server_id); |
682 } | 681 } |
683 | 682 |
684 QuicConnectionId connection_id = random_generator_->RandUint64(); | 683 QuicConnectionId connection_id = random_generator_->RandUint64(); |
685 IPEndPoint addr = *address_list.begin(); | 684 IPEndPoint addr = *address_list.begin(); |
686 scoped_refptr<PortSuggester> port_suggester = | 685 scoped_refptr<PortSuggester> port_suggester = |
687 new PortSuggester(server_id.host_port_pair(), port_seed_); | 686 new PortSuggester(server_id.host_port_pair(), port_seed_); |
688 DatagramSocket::BindType bind_type = enable_port_selection ? | 687 DatagramSocket::BindType bind_type = |
689 DatagramSocket::RANDOM_BIND : // Use our callback. | 688 enable_port_selection ? DatagramSocket::RANDOM_BIND |
690 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 689 : // Use our callback. |
| 690 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
691 scoped_ptr<DatagramClientSocket> socket( | 691 scoped_ptr<DatagramClientSocket> socket( |
692 client_socket_factory_->CreateDatagramClientSocket( | 692 client_socket_factory_->CreateDatagramClientSocket( |
693 bind_type, | 693 bind_type, |
694 base::Bind(&PortSuggester::SuggestPort, port_suggester), | 694 base::Bind(&PortSuggester::SuggestPort, port_suggester), |
695 net_log.net_log(), net_log.source())); | 695 net_log.net_log(), |
| 696 net_log.source())); |
696 int rv = socket->Connect(addr); | 697 int rv = socket->Connect(addr); |
697 if (rv != OK) { | 698 if (rv != OK) { |
698 HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET); | 699 HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET); |
699 return rv; | 700 return rv; |
700 } | 701 } |
701 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested", | 702 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested", |
702 port_suggester->call_count()); | 703 port_suggester->call_count()); |
703 if (enable_port_selection) { | 704 if (enable_port_selection) { |
704 DCHECK_LE(1u, port_suggester->call_count()); | 705 DCHECK_LE(1u, port_suggester->call_count()); |
705 } else { | 706 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
724 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_SEND_BUFFER); | 725 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_SEND_BUFFER); |
725 return rv; | 726 return rv; |
726 } | 727 } |
727 | 728 |
728 scoped_ptr<QuicDefaultPacketWriter> writer( | 729 scoped_ptr<QuicDefaultPacketWriter> writer( |
729 new QuicDefaultPacketWriter(socket.get())); | 730 new QuicDefaultPacketWriter(socket.get())); |
730 | 731 |
731 if (!helper_.get()) { | 732 if (!helper_.get()) { |
732 helper_.reset(new QuicConnectionHelper( | 733 helper_.reset(new QuicConnectionHelper( |
733 base::MessageLoop::current()->message_loop_proxy().get(), | 734 base::MessageLoop::current()->message_loop_proxy().get(), |
734 clock_.get(), random_generator_)); | 735 clock_.get(), |
| 736 random_generator_)); |
735 } | 737 } |
736 | 738 |
737 QuicConnection* connection = | 739 QuicConnection* connection = new QuicConnection(connection_id, |
738 new QuicConnection(connection_id, addr, helper_.get(), writer.get(), | 740 addr, |
739 false, supported_versions_, kInitialReceiveWindowSize); | 741 helper_.get(), |
| 742 writer.get(), |
| 743 false, |
| 744 supported_versions_, |
| 745 kInitialReceiveWindowSize); |
740 writer->SetConnection(connection); | 746 writer->SetConnection(connection); |
741 connection->options()->max_packet_length = max_packet_length_; | 747 connection->options()->max_packet_length = max_packet_length_; |
742 | 748 |
743 InitializeCachedStateInCryptoConfig(server_id, server_info); | 749 InitializeCachedStateInCryptoConfig(server_id, server_info); |
744 | 750 |
745 QuicConfig config = config_; | 751 QuicConfig config = config_; |
746 if (http_server_properties_) { | 752 if (http_server_properties_) { |
747 const HttpServerProperties::NetworkStats* stats = | 753 const HttpServerProperties::NetworkStats* stats = |
748 http_server_properties_->GetServerNetworkStats( | 754 http_server_properties_->GetServerNetworkStats( |
749 server_id.host_port_pair()); | 755 server_id.host_port_pair()); |
750 if (stats != NULL) { | 756 if (stats != NULL) { |
751 config.SetInitialRoundTripTimeUsToSend(stats->srtt.InMicroseconds()); | 757 config.SetInitialRoundTripTimeUsToSend(stats->srtt.InMicroseconds()); |
752 } | 758 } |
753 } | 759 } |
754 | 760 |
755 *session = new QuicClientSession( | 761 *session = new QuicClientSession(connection, |
756 connection, socket.Pass(), writer.Pass(), this, | 762 socket.Pass(), |
757 quic_crypto_client_stream_factory_, server_info.Pass(), server_id, | 763 writer.Pass(), |
758 config, &crypto_config_, net_log.net_log()); | 764 this, |
| 765 quic_crypto_client_stream_factory_, |
| 766 server_info.Pass(), |
| 767 server_id, |
| 768 config, |
| 769 &crypto_config_, |
| 770 net_log.net_log()); |
759 all_sessions_[*session] = server_id; // owning pointer | 771 all_sessions_[*session] = server_id; // owning pointer |
760 return OK; | 772 return OK; |
761 } | 773 } |
762 | 774 |
763 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | 775 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { |
764 return ContainsKey(active_jobs_, key); | 776 return ContainsKey(active_jobs_, key); |
765 } | 777 } |
766 | 778 |
767 void QuicStreamFactory::ActivateSession( | 779 void QuicStreamFactory::ActivateSession(const QuicServerId& server_id, |
768 const QuicServerId& server_id, | 780 QuicClientSession* session) { |
769 QuicClientSession* session) { | |
770 DCHECK(!HasActiveSession(server_id)); | 781 DCHECK(!HasActiveSession(server_id)); |
771 active_sessions_[server_id] = session; | 782 active_sessions_[server_id] = session; |
772 session_aliases_[session].insert(server_id); | 783 session_aliases_[session].insert(server_id); |
773 const IpAliasKey ip_alias_key(session->connection()->peer_address(), | 784 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
774 server_id.is_https()); | 785 server_id.is_https()); |
775 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); | 786 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); |
776 ip_aliases_[ip_alias_key].insert(session); | 787 ip_aliases_[ip_alias_key].insert(session); |
777 } | 788 } |
778 | 789 |
779 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( | 790 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( |
(...skipping 13 matching lines...) Expand all Loading... |
793 server_info->state().server_config_sig, | 804 server_info->state().server_config_sig, |
794 clock_->WallNow())) | 805 clock_->WallNow())) |
795 return; | 806 return; |
796 | 807 |
797 if (!server_id.is_https()) { | 808 if (!server_id.is_https()) { |
798 // Don't check the certificates for insecure QUIC. | 809 // Don't check the certificates for insecure QUIC. |
799 cached->SetProofValid(); | 810 cached->SetProofValid(); |
800 } | 811 } |
801 } | 812 } |
802 | 813 |
803 void QuicStreamFactory::ProcessGoingAwaySession( | 814 void QuicStreamFactory::ProcessGoingAwaySession(QuicClientSession* session, |
804 QuicClientSession* session, | 815 const QuicServerId& server_id) { |
805 const QuicServerId& server_id) { | |
806 if (!http_server_properties_) | 816 if (!http_server_properties_) |
807 return; | 817 return; |
808 | 818 |
809 const QuicConnectionStats& stats = session->connection()->GetStats(); | 819 const QuicConnectionStats& stats = session->connection()->GetStats(); |
810 if (!session->IsCryptoHandshakeConfirmed()) { | 820 if (!session->IsCryptoHandshakeConfirmed()) { |
811 // TODO(rch): In the special case where the session has received no | 821 // TODO(rch): In the special case where the session has received no |
812 // packets from the peer, we should consider blacklisting this | 822 // packets from the peer, we should consider blacklisting this |
813 // differently so that we still race TCP but we don't consider the | 823 // differently so that we still race TCP but we don't consider the |
814 // session connected until the handshake has been confirmed. | 824 // session connected until the handshake has been confirmed. |
815 HistogramBrokenAlternateProtocolLocation( | 825 HistogramBrokenAlternateProtocolLocation( |
816 BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_STREAM_FACTORY); | 826 BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_STREAM_FACTORY); |
817 http_server_properties_->SetBrokenAlternateProtocol( | 827 http_server_properties_->SetBrokenAlternateProtocol( |
818 server_id.host_port_pair()); | 828 server_id.host_port_pair()); |
819 UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived", | 829 UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived", |
820 stats.packets_received); | 830 stats.packets_received); |
821 return; | 831 return; |
822 } | 832 } |
823 | 833 |
824 HttpServerProperties::NetworkStats network_stats; | 834 HttpServerProperties::NetworkStats network_stats; |
825 network_stats.srtt = base::TimeDelta::FromMicroseconds(stats.srtt_us); | 835 network_stats.srtt = base::TimeDelta::FromMicroseconds(stats.srtt_us); |
826 network_stats.bandwidth_estimate = stats.estimated_bandwidth; | 836 network_stats.bandwidth_estimate = stats.estimated_bandwidth; |
827 http_server_properties_->SetServerNetworkStats(server_id.host_port_pair(), | 837 http_server_properties_->SetServerNetworkStats(server_id.host_port_pair(), |
828 network_stats); | 838 network_stats); |
829 } | 839 } |
830 | 840 |
831 } // namespace net | 841 } // namespace net |
OLD | NEW |