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" |
11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
12 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/profiler/scoped_tracker.h" | 14 #include "base/profiler/scoped_tracker.h" |
15 #include "base/rand_util.h" | 15 #include "base/rand_util.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
18 #include "base/values.h" | 18 #include "base/values.h" |
19 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
20 #include "net/cert/cert_verifier.h" | 20 #include "net/cert/cert_verifier.h" |
21 #include "net/dns/host_resolver.h" | 21 #include "net/dns/host_resolver.h" |
22 #include "net/dns/single_request_host_resolver.h" | 22 #include "net/dns/single_request_host_resolver.h" |
23 #include "net/http/http_server_properties.h" | 23 #include "net/http/http_server_properties.h" |
24 #include "net/quic/congestion_control/tcp_receiver.h" | |
25 #include "net/quic/crypto/channel_id_chromium.h" | 24 #include "net/quic/crypto/channel_id_chromium.h" |
26 #include "net/quic/crypto/proof_verifier_chromium.h" | 25 #include "net/quic/crypto/proof_verifier_chromium.h" |
27 #include "net/quic/crypto/quic_random.h" | 26 #include "net/quic/crypto/quic_random.h" |
28 #include "net/quic/crypto/quic_server_info.h" | 27 #include "net/quic/crypto/quic_server_info.h" |
29 #include "net/quic/port_suggester.h" | 28 #include "net/quic/port_suggester.h" |
30 #include "net/quic/quic_client_session.h" | 29 #include "net/quic/quic_client_session.h" |
31 #include "net/quic/quic_clock.h" | 30 #include "net/quic/quic_clock.h" |
32 #include "net/quic/quic_connection.h" | 31 #include "net/quic/quic_connection.h" |
33 #include "net/quic/quic_connection_helper.h" | 32 #include "net/quic/quic_connection_helper.h" |
34 #include "net/quic/quic_crypto_client_stream_factory.h" | 33 #include "net/quic/quic_crypto_client_stream_factory.h" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 // Responsible for creating a new QUIC session to the specified server, and | 133 // Responsible for creating a new QUIC session to the specified server, and |
135 // for notifying any associated requests when complete. | 134 // for notifying any associated requests when complete. |
136 class QuicStreamFactory::Job { | 135 class QuicStreamFactory::Job { |
137 public: | 136 public: |
138 Job(QuicStreamFactory* factory, | 137 Job(QuicStreamFactory* factory, |
139 HostResolver* host_resolver, | 138 HostResolver* host_resolver, |
140 const HostPortPair& host_port_pair, | 139 const HostPortPair& host_port_pair, |
141 bool is_https, | 140 bool is_https, |
142 bool was_alternate_protocol_recently_broken, | 141 bool was_alternate_protocol_recently_broken, |
143 PrivacyMode privacy_mode, | 142 PrivacyMode privacy_mode, |
144 base::StringPiece method, | 143 bool is_post, |
145 QuicServerInfo* server_info, | 144 QuicServerInfo* server_info, |
146 const BoundNetLog& net_log); | 145 const BoundNetLog& net_log); |
147 | 146 |
148 // Creates a new job to handle the resumption of for connecting an | 147 // Creates a new job to handle the resumption of for connecting an |
149 // existing session. | 148 // existing session. |
150 Job(QuicStreamFactory* factory, | 149 Job(QuicStreamFactory* factory, |
151 HostResolver* host_resolver, | 150 HostResolver* host_resolver, |
152 QuicClientSession* session, | 151 QuicClientSession* session, |
153 QuicServerId server_id); | 152 QuicServerId server_id); |
154 | 153 |
155 ~Job(); | 154 ~Job(); |
156 | 155 |
157 int Run(const CompletionCallback& callback); | 156 int Run(const CompletionCallback& callback); |
158 | 157 |
159 int DoLoop(int rv); | 158 int DoLoop(int rv); |
160 int DoResolveHost(); | 159 int DoResolveHost(); |
161 int DoResolveHostComplete(int rv); | 160 int DoResolveHostComplete(int rv); |
162 int DoLoadServerInfo(); | 161 int DoLoadServerInfo(); |
163 int DoLoadServerInfoComplete(int rv); | 162 int DoLoadServerInfoComplete(int rv); |
164 int DoConnect(); | 163 int DoConnect(); |
165 int DoResumeConnect(); | 164 int DoResumeConnect(); |
166 int DoConnectComplete(int rv); | 165 int DoConnectComplete(int rv); |
167 | 166 |
168 void OnIOComplete(int rv); | 167 void OnIOComplete(int rv); |
169 | 168 |
| 169 void RunAuxilaryJob(); |
| 170 |
| 171 void Cancel(); |
| 172 |
170 void CancelWaitForDataReadyCallback(); | 173 void CancelWaitForDataReadyCallback(); |
171 | 174 |
172 CompletionCallback callback() { | 175 const QuicServerId server_id() const { return server_id_; } |
173 return callback_; | |
174 } | |
175 | 176 |
176 const QuicServerId server_id() const { | 177 base::WeakPtr<Job> GetWeakPtr() { return weak_factory_.GetWeakPtr(); } |
177 return server_id_; | |
178 } | |
179 | 178 |
180 private: | 179 private: |
181 enum IoState { | 180 enum IoState { |
182 STATE_NONE, | 181 STATE_NONE, |
183 STATE_RESOLVE_HOST, | 182 STATE_RESOLVE_HOST, |
184 STATE_RESOLVE_HOST_COMPLETE, | 183 STATE_RESOLVE_HOST_COMPLETE, |
185 STATE_LOAD_SERVER_INFO, | 184 STATE_LOAD_SERVER_INFO, |
186 STATE_LOAD_SERVER_INFO_COMPLETE, | 185 STATE_LOAD_SERVER_INFO_COMPLETE, |
187 STATE_CONNECT, | 186 STATE_CONNECT, |
188 STATE_RESUME_CONNECT, | 187 STATE_RESUME_CONNECT, |
189 STATE_CONNECT_COMPLETE, | 188 STATE_CONNECT_COMPLETE, |
190 }; | 189 }; |
191 IoState io_state_; | 190 IoState io_state_; |
192 | 191 |
193 QuicStreamFactory* factory_; | 192 QuicStreamFactory* factory_; |
194 SingleRequestHostResolver host_resolver_; | 193 SingleRequestHostResolver host_resolver_; |
195 QuicServerId server_id_; | 194 QuicServerId server_id_; |
196 bool is_post_; | 195 bool is_post_; |
197 bool was_alternate_protocol_recently_broken_; | 196 bool was_alternate_protocol_recently_broken_; |
198 scoped_ptr<QuicServerInfo> server_info_; | 197 scoped_ptr<QuicServerInfo> server_info_; |
| 198 bool started_another_job_; |
199 const BoundNetLog net_log_; | 199 const BoundNetLog net_log_; |
200 QuicClientSession* session_; | 200 QuicClientSession* session_; |
201 CompletionCallback callback_; | 201 CompletionCallback callback_; |
202 AddressList address_list_; | 202 AddressList address_list_; |
203 base::TimeTicks disk_cache_load_start_time_; | 203 base::TimeTicks disk_cache_load_start_time_; |
204 base::TimeTicks dns_resolution_start_time_; | 204 base::TimeTicks dns_resolution_start_time_; |
205 base::WeakPtrFactory<Job> weak_factory_; | 205 base::WeakPtrFactory<Job> weak_factory_; |
206 DISALLOW_COPY_AND_ASSIGN(Job); | 206 DISALLOW_COPY_AND_ASSIGN(Job); |
207 }; | 207 }; |
208 | 208 |
209 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 209 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
210 HostResolver* host_resolver, | 210 HostResolver* host_resolver, |
211 const HostPortPair& host_port_pair, | 211 const HostPortPair& host_port_pair, |
212 bool is_https, | 212 bool is_https, |
213 bool was_alternate_protocol_recently_broken, | 213 bool was_alternate_protocol_recently_broken, |
214 PrivacyMode privacy_mode, | 214 PrivacyMode privacy_mode, |
215 base::StringPiece method, | 215 bool is_post, |
216 QuicServerInfo* server_info, | 216 QuicServerInfo* server_info, |
217 const BoundNetLog& net_log) | 217 const BoundNetLog& net_log) |
218 : io_state_(STATE_RESOLVE_HOST), | 218 : io_state_(STATE_RESOLVE_HOST), |
219 factory_(factory), | 219 factory_(factory), |
220 host_resolver_(host_resolver), | 220 host_resolver_(host_resolver), |
221 server_id_(host_port_pair, is_https, privacy_mode), | 221 server_id_(host_port_pair, is_https, privacy_mode), |
222 is_post_(method == "POST"), | 222 is_post_(is_post), |
223 was_alternate_protocol_recently_broken_( | 223 was_alternate_protocol_recently_broken_( |
224 was_alternate_protocol_recently_broken), | 224 was_alternate_protocol_recently_broken), |
225 server_info_(server_info), | 225 server_info_(server_info), |
| 226 started_another_job_(false), |
226 net_log_(net_log), | 227 net_log_(net_log), |
227 session_(nullptr), | 228 session_(nullptr), |
228 weak_factory_(this) {} | 229 weak_factory_(this) { |
| 230 } |
229 | 231 |
230 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 232 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
231 HostResolver* host_resolver, | 233 HostResolver* host_resolver, |
232 QuicClientSession* session, | 234 QuicClientSession* session, |
233 QuicServerId server_id) | 235 QuicServerId server_id) |
234 : io_state_(STATE_RESUME_CONNECT), | 236 : io_state_(STATE_RESUME_CONNECT), |
235 factory_(factory), | 237 factory_(factory), |
236 host_resolver_(host_resolver), // unused | 238 host_resolver_(host_resolver), // unused |
237 server_id_(server_id), | 239 server_id_(server_id), |
238 is_post_(false), // unused | 240 is_post_(false), // unused |
239 was_alternate_protocol_recently_broken_(false), // unused | 241 was_alternate_protocol_recently_broken_(false), // unused |
240 net_log_(session->net_log()), // unused | 242 started_another_job_(false), // unused |
| 243 net_log_(session->net_log()), // unused |
241 session_(session), | 244 session_(session), |
242 weak_factory_(this) {} | 245 weak_factory_(this) { |
| 246 } |
243 | 247 |
244 QuicStreamFactory::Job::~Job() { | 248 QuicStreamFactory::Job::~Job() { |
| 249 // If disk cache has a pending WaitForDataReadyCallback, cancel that callback. |
| 250 if (server_info_) |
| 251 server_info_->ResetWaitForDataReadyCallback(); |
245 } | 252 } |
246 | 253 |
247 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 254 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
248 int rv = DoLoop(OK); | 255 int rv = DoLoop(OK); |
249 if (rv == ERR_IO_PENDING) | 256 if (rv == ERR_IO_PENDING) |
250 callback_ = callback; | 257 callback_ = callback; |
251 | 258 |
252 return rv > 0 ? OK : rv; | 259 return rv > 0 ? OK : rv; |
253 } | 260 } |
254 | 261 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 | 307 |
301 tracked_objects::ScopedTracker tracking_profile2( | 308 tracked_objects::ScopedTracker tracking_profile2( |
302 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 309 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
303 "422516 QuicStreamFactory::Job::OnIOComplete2")); | 310 "422516 QuicStreamFactory::Job::OnIOComplete2")); |
304 | 311 |
305 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 312 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
306 callback_.Run(rv); | 313 callback_.Run(rv); |
307 } | 314 } |
308 } | 315 } |
309 | 316 |
| 317 void QuicStreamFactory::Job::RunAuxilaryJob() { |
| 318 int rv = Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 319 base::Unretained(factory_), this)); |
| 320 if (rv != ERR_IO_PENDING) |
| 321 factory_->OnJobComplete(this, rv); |
| 322 } |
| 323 |
| 324 void QuicStreamFactory::Job::Cancel() { |
| 325 callback_.Reset(); |
| 326 if (session_) |
| 327 session_->connection()->SendConnectionClose(QUIC_CONNECTION_CANCELLED); |
| 328 } |
| 329 |
310 void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { | 330 void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { |
311 // If we are waiting for WaitForDataReadyCallback, then cancel the callback. | 331 // If we are waiting for WaitForDataReadyCallback, then cancel the callback. |
312 if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) | 332 if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) |
313 return; | 333 return; |
314 server_info_->CancelWaitForDataReadyCallback(); | 334 server_info_->CancelWaitForDataReadyCallback(); |
315 OnIOComplete(OK); | 335 OnIOComplete(OK); |
316 } | 336 } |
317 | 337 |
318 int QuicStreamFactory::Job::DoResolveHost() { | 338 int QuicStreamFactory::Job::DoResolveHost() { |
319 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 339 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
320 tracked_objects::ScopedTracker tracking_profile( | 340 tracked_objects::ScopedTracker tracking_profile( |
321 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 341 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
322 "422516 QuicStreamFactory::Job::DoResolveHost")); | 342 "422516 QuicStreamFactory::Job::DoResolveHost")); |
323 | 343 |
324 // Start loading the data now, and wait for it after we resolve the host. | 344 // Start loading the data now, and wait for it after we resolve the host. |
325 if (server_info_) { | 345 if (server_info_) { |
326 server_info_->Start(); | 346 server_info_->Start(); |
327 } | 347 } |
328 | 348 |
329 io_state_ = STATE_RESOLVE_HOST_COMPLETE; | 349 io_state_ = STATE_RESOLVE_HOST_COMPLETE; |
330 dns_resolution_start_time_ = base::TimeTicks::Now(); | 350 dns_resolution_start_time_ = base::TimeTicks::Now(); |
331 return host_resolver_.Resolve( | 351 return host_resolver_.Resolve( |
332 HostResolver::RequestInfo(server_id_.host_port_pair()), | 352 HostResolver::RequestInfo(server_id_.host_port_pair()), DEFAULT_PRIORITY, |
333 DEFAULT_PRIORITY, | |
334 &address_list_, | 353 &address_list_, |
335 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 354 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr()), |
336 weak_factory_.GetWeakPtr()), | |
337 net_log_); | 355 net_log_); |
338 } | 356 } |
339 | 357 |
340 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { | 358 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { |
341 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 359 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
342 tracked_objects::ScopedTracker tracking_profile( | 360 tracked_objects::ScopedTracker tracking_profile( |
343 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 361 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
344 "422516 QuicStreamFactory::Job::DoResolveHostComplete")); | 362 "422516 QuicStreamFactory::Job::DoResolveHostComplete")); |
345 | 363 |
346 UMA_HISTOGRAM_TIMES("Net.QuicSession.HostResolutionTime", | 364 UMA_HISTOGRAM_TIMES("Net.QuicSession.HostResolutionTime", |
347 base::TimeTicks::Now() - dns_resolution_start_time_); | 365 base::TimeTicks::Now() - dns_resolution_start_time_); |
348 if (rv != OK) | 366 if (rv != OK) |
349 return rv; | 367 return rv; |
350 | 368 |
351 DCHECK(!factory_->HasActiveSession(server_id_)); | 369 DCHECK(!factory_->HasActiveSession(server_id_)); |
352 | 370 |
353 // Inform the factory of this resolution, which will set up | 371 // Inform the factory of this resolution, which will set up |
354 // a session alias, if possible. | 372 // a session alias, if possible. |
355 if (factory_->OnResolution(server_id_, address_list_)) { | 373 if (factory_->OnResolution(server_id_, address_list_)) { |
356 return OK; | 374 return OK; |
357 } | 375 } |
358 | 376 |
359 io_state_ = STATE_LOAD_SERVER_INFO; | 377 if (server_info_) |
| 378 io_state_ = STATE_LOAD_SERVER_INFO; |
| 379 else |
| 380 io_state_ = STATE_CONNECT; |
360 return OK; | 381 return OK; |
361 } | 382 } |
362 | 383 |
363 int QuicStreamFactory::Job::DoLoadServerInfo() { | 384 int QuicStreamFactory::Job::DoLoadServerInfo() { |
364 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 385 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
365 tracked_objects::ScopedTracker tracking_profile( | 386 tracked_objects::ScopedTracker tracking_profile( |
366 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 387 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
367 "422516 QuicStreamFactory::Job::DoLoadServerInfo")); | 388 "422516 QuicStreamFactory::Job::DoLoadServerInfo")); |
368 | 389 |
369 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; | 390 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; |
370 | 391 |
371 if (!server_info_) | 392 DCHECK(server_info_); |
372 return OK; | |
373 | 393 |
374 // To mitigate the effects of disk cache taking too long to load QUIC server | 394 // To mitigate the effects of disk cache taking too long to load QUIC server |
375 // information, set up a timer to cancel WaitForDataReady's callback. | 395 // information, set up a timer to cancel WaitForDataReady's callback. |
376 int64 load_server_info_timeout_ms = factory_->load_server_info_timeout_ms_; | 396 int64 load_server_info_timeout_ms = factory_->load_server_info_timeout_ms_; |
377 if (factory_->load_server_info_timeout_srtt_multiplier_ > 0) { | 397 if (factory_->load_server_info_timeout_srtt_multiplier_ > 0) { |
378 DCHECK_EQ(0, load_server_info_timeout_ms); | 398 DCHECK_EQ(0, load_server_info_timeout_ms); |
379 load_server_info_timeout_ms = | 399 load_server_info_timeout_ms = |
380 (factory_->load_server_info_timeout_srtt_multiplier_ * | 400 (factory_->load_server_info_timeout_srtt_multiplier_ * |
381 factory_->GetServerNetworkStatsSmoothedRttInMicroseconds(server_id_)) / | 401 factory_->GetServerNetworkStatsSmoothedRttInMicroseconds(server_id_)) / |
382 1000; | 402 1000; |
383 } | 403 } |
384 if (load_server_info_timeout_ms > 0) { | 404 if (load_server_info_timeout_ms > 0) { |
385 factory_->task_runner_->PostDelayedTask( | 405 factory_->task_runner_->PostDelayedTask( |
386 FROM_HERE, | 406 FROM_HERE, |
387 base::Bind(&QuicStreamFactory::Job::CancelWaitForDataReadyCallback, | 407 base::Bind(&QuicStreamFactory::Job::CancelWaitForDataReadyCallback, |
388 weak_factory_.GetWeakPtr()), | 408 GetWeakPtr()), |
389 base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); | 409 base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); |
390 } | 410 } |
391 | 411 |
392 disk_cache_load_start_time_ = base::TimeTicks::Now(); | 412 disk_cache_load_start_time_ = base::TimeTicks::Now(); |
393 return server_info_->WaitForDataReady( | 413 int rv = server_info_->WaitForDataReady( |
394 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 414 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
395 weak_factory_.GetWeakPtr())); | 415 if (rv == ERR_IO_PENDING && factory_->enable_connection_racing()) { |
| 416 // If we are waiting to load server config from the disk cache, then start |
| 417 // another job. |
| 418 started_another_job_ = true; |
| 419 factory_->CreateAuxilaryJob(server_id_, is_post_, net_log_); |
| 420 } |
| 421 return rv; |
396 } | 422 } |
397 | 423 |
398 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { | 424 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { |
399 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 425 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
400 tracked_objects::ScopedTracker tracking_profile( | 426 tracked_objects::ScopedTracker tracking_profile( |
401 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 427 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
402 "422516 QuicStreamFactory::Job::DoLoadServerInfoComplete")); | 428 "422516 QuicStreamFactory::Job::DoLoadServerInfoComplete")); |
403 | 429 |
404 if (server_info_) { | 430 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", |
405 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", | 431 base::TimeTicks::Now() - disk_cache_load_start_time_); |
406 base::TimeTicks::Now() - disk_cache_load_start_time_); | |
407 } | |
408 | 432 |
409 if (rv != OK) { | 433 if (rv != OK) |
410 server_info_.reset(); | 434 server_info_.reset(); |
| 435 |
| 436 if (started_another_job_ && |
| 437 (!server_info_ || server_info_->state().server_config.empty() || |
| 438 !factory_->CryptoConfigCacheIsEmpty(server_id_))) { |
| 439 // If we have started another job and if we didn't load the server config |
| 440 // from the disk cache or if we have received a new server config from the |
| 441 // server, then cancel the current job. |
| 442 io_state_ = STATE_NONE; |
| 443 return ERR_CONNECTION_CLOSED; |
411 } | 444 } |
412 | 445 |
413 io_state_ = STATE_CONNECT; | 446 io_state_ = STATE_CONNECT; |
414 return OK; | 447 return OK; |
415 } | 448 } |
416 | 449 |
417 int QuicStreamFactory::Job::DoConnect() { | 450 int QuicStreamFactory::Job::DoConnect() { |
418 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 451 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
419 tracked_objects::ScopedTracker tracking_profile( | 452 tracked_objects::ScopedTracker tracking_profile( |
420 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 453 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
(...skipping 26 matching lines...) Expand all Loading... |
447 factory_->require_confirmation() || is_post_ || | 480 factory_->require_confirmation() || is_post_ || |
448 was_alternate_protocol_recently_broken_; | 481 was_alternate_protocol_recently_broken_; |
449 | 482 |
450 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 483 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
451 tracked_objects::ScopedTracker tracking_profile2( | 484 tracked_objects::ScopedTracker tracking_profile2( |
452 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 485 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
453 "422516 QuicStreamFactory::Job::DoConnect2")); | 486 "422516 QuicStreamFactory::Job::DoConnect2")); |
454 | 487 |
455 rv = session_->CryptoConnect( | 488 rv = session_->CryptoConnect( |
456 require_confirmation, | 489 require_confirmation, |
457 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 490 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
458 base::Unretained(this))); | |
459 return rv; | 491 return rv; |
460 } | 492 } |
461 | 493 |
462 int QuicStreamFactory::Job::DoResumeConnect() { | 494 int QuicStreamFactory::Job::DoResumeConnect() { |
463 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 495 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
464 tracked_objects::ScopedTracker tracking_profile( | 496 tracked_objects::ScopedTracker tracking_profile( |
465 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 497 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
466 "422516 QuicStreamFactory::Job::DoResumeConnect")); | 498 "422516 QuicStreamFactory::Job::DoResumeConnect")); |
467 | 499 |
468 io_state_ = STATE_CONNECT_COMPLETE; | 500 io_state_ = STATE_CONNECT_COMPLETE; |
469 | 501 |
470 int rv = session_->ResumeCryptoConnect( | 502 int rv = session_->ResumeCryptoConnect( |
471 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 503 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
472 base::Unretained(this))); | |
473 | 504 |
474 return rv; | 505 return rv; |
475 } | 506 } |
476 | 507 |
477 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 508 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
478 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 509 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
479 tracked_objects::ScopedTracker tracking_profile( | 510 tracked_objects::ScopedTracker tracking_profile( |
480 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 511 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
481 "422516 QuicStreamFactory::Job::DoConnectComplete")); | 512 "422516 QuicStreamFactory::Job::DoConnectComplete")); |
482 | 513 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 QuicClock* clock, | 588 QuicClock* clock, |
558 size_t max_packet_length, | 589 size_t max_packet_length, |
559 const std::string& user_agent_id, | 590 const std::string& user_agent_id, |
560 const QuicVersionVector& supported_versions, | 591 const QuicVersionVector& supported_versions, |
561 bool enable_port_selection, | 592 bool enable_port_selection, |
562 bool always_require_handshake_confirmation, | 593 bool always_require_handshake_confirmation, |
563 bool disable_connection_pooling, | 594 bool disable_connection_pooling, |
564 int load_server_info_timeout, | 595 int load_server_info_timeout, |
565 float load_server_info_timeout_srtt_multiplier, | 596 float load_server_info_timeout_srtt_multiplier, |
566 bool enable_truncated_connection_ids, | 597 bool enable_truncated_connection_ids, |
| 598 bool enable_connection_racing, |
567 const QuicTagVector& connection_options) | 599 const QuicTagVector& connection_options) |
568 : require_confirmation_(true), | 600 : require_confirmation_(true), |
569 host_resolver_(host_resolver), | 601 host_resolver_(host_resolver), |
570 client_socket_factory_(client_socket_factory), | 602 client_socket_factory_(client_socket_factory), |
571 http_server_properties_(http_server_properties), | 603 http_server_properties_(http_server_properties), |
572 transport_security_state_(transport_security_state), | 604 transport_security_state_(transport_security_state), |
573 quic_server_info_factory_(nullptr), | 605 quic_server_info_factory_(nullptr), |
574 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), | 606 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), |
575 random_generator_(random_generator), | 607 random_generator_(random_generator), |
576 clock_(clock), | 608 clock_(clock), |
577 max_packet_length_(max_packet_length), | 609 max_packet_length_(max_packet_length), |
578 config_(InitializeQuicConfig(connection_options)), | 610 config_(InitializeQuicConfig(connection_options)), |
579 supported_versions_(supported_versions), | 611 supported_versions_(supported_versions), |
580 enable_port_selection_(enable_port_selection), | 612 enable_port_selection_(enable_port_selection), |
581 always_require_handshake_confirmation_( | 613 always_require_handshake_confirmation_( |
582 always_require_handshake_confirmation), | 614 always_require_handshake_confirmation), |
583 disable_connection_pooling_(disable_connection_pooling), | 615 disable_connection_pooling_(disable_connection_pooling), |
584 load_server_info_timeout_ms_(load_server_info_timeout), | 616 load_server_info_timeout_ms_(load_server_info_timeout), |
585 load_server_info_timeout_srtt_multiplier_( | 617 load_server_info_timeout_srtt_multiplier_( |
586 load_server_info_timeout_srtt_multiplier), | 618 load_server_info_timeout_srtt_multiplier), |
587 enable_truncated_connection_ids_(enable_truncated_connection_ids), | 619 enable_truncated_connection_ids_(enable_truncated_connection_ids), |
| 620 enable_connection_racing_(enable_connection_racing), |
588 port_seed_(random_generator_->RandUint64()), | 621 port_seed_(random_generator_->RandUint64()), |
589 check_persisted_supports_quic_(true), | 622 check_persisted_supports_quic_(true), |
590 task_runner_(nullptr), | 623 task_runner_(nullptr), |
591 weak_factory_(this) { | 624 weak_factory_(this) { |
592 DCHECK(transport_security_state_); | 625 DCHECK(transport_security_state_); |
| 626 // TODO(michaeln): Remove ScopedTracker below once crbug.com/454983 is fixed |
| 627 tracked_objects::ScopedTracker tracking_profile( |
| 628 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 629 "454983 QuicStreamFactory::QuicStreamFactory")); |
593 crypto_config_.set_user_agent_id(user_agent_id); | 630 crypto_config_.set_user_agent_id(user_agent_id); |
594 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); | 631 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); |
595 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); | 632 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); |
596 crypto_config_.SetProofVerifier( | 633 crypto_config_.SetProofVerifier( |
597 new ProofVerifierChromium(cert_verifier, transport_security_state)); | 634 new ProofVerifierChromium(cert_verifier, transport_security_state)); |
598 crypto_config_.SetChannelIDSource( | 635 crypto_config_.SetChannelIDSource( |
599 new ChannelIDSourceChromium(channel_id_service)); | 636 new ChannelIDSourceChromium(channel_id_service)); |
600 base::CPU cpu; | 637 base::CPU cpu; |
601 if (cpu.has_aesni() && cpu.has_avx()) | 638 if (cpu.has_aesni() && cpu.has_avx()) |
602 crypto_config_.PreferAesGcm(); | 639 crypto_config_.PreferAesGcm(); |
603 if (!IsEcdsaSupported()) | 640 if (!IsEcdsaSupported()) |
604 crypto_config_.DisableEcdsa(); | 641 crypto_config_.DisableEcdsa(); |
605 } | 642 } |
606 | 643 |
607 QuicStreamFactory::~QuicStreamFactory() { | 644 QuicStreamFactory::~QuicStreamFactory() { |
608 CloseAllSessions(ERR_ABORTED); | 645 CloseAllSessions(ERR_ABORTED); |
609 while (!all_sessions_.empty()) { | 646 while (!all_sessions_.empty()) { |
610 delete all_sessions_.begin()->first; | 647 delete all_sessions_.begin()->first; |
611 all_sessions_.erase(all_sessions_.begin()); | 648 all_sessions_.erase(all_sessions_.begin()); |
612 } | 649 } |
613 STLDeleteValues(&active_jobs_); | 650 while (!active_jobs_.empty()) { |
| 651 const QuicServerId server_id = active_jobs_.begin()->first; |
| 652 STLDeleteElements(&(active_jobs_[server_id])); |
| 653 active_jobs_.erase(server_id); |
| 654 } |
614 } | 655 } |
615 | 656 |
616 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { | 657 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { |
617 require_confirmation_ = require_confirmation; | 658 require_confirmation_ = require_confirmation; |
618 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { | 659 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { |
619 http_server_properties_->SetSupportsQuic(!require_confirmation, | 660 http_server_properties_->SetSupportsQuic(!require_confirmation, |
620 local_address_.address()); | 661 local_address_.address()); |
621 } | 662 } |
622 } | 663 } |
623 | 664 |
624 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, | 665 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, |
625 bool is_https, | 666 bool is_https, |
626 PrivacyMode privacy_mode, | 667 PrivacyMode privacy_mode, |
627 base::StringPiece method, | 668 base::StringPiece method, |
628 const BoundNetLog& net_log, | 669 const BoundNetLog& net_log, |
629 QuicStreamRequest* request) { | 670 QuicStreamRequest* request) { |
630 QuicServerId server_id(host_port_pair, is_https, privacy_mode); | 671 QuicServerId server_id(host_port_pair, is_https, privacy_mode); |
631 if (HasActiveSession(server_id)) { | 672 if (HasActiveSession(server_id)) { |
632 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 673 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
633 return OK; | 674 return OK; |
634 } | 675 } |
635 | 676 |
636 if (HasActiveJob(server_id)) { | 677 if (HasActiveJob(server_id)) { |
637 Job* job = active_jobs_[server_id]; | 678 active_requests_[request] = server_id; |
638 active_requests_[request] = job; | 679 job_requests_map_[server_id].insert(request); |
639 job_requests_map_[job].insert(request); | |
640 return ERR_IO_PENDING; | 680 return ERR_IO_PENDING; |
641 } | 681 } |
642 | 682 |
| 683 // TODO(rtenneti): |task_runner_| is used by the Job. Initialize task_runner_ |
| 684 // in the constructor after WebRequestActionWithThreadsTest.* tests are fixed. |
| 685 if (!task_runner_) |
| 686 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); |
| 687 |
643 QuicServerInfo* quic_server_info = nullptr; | 688 QuicServerInfo* quic_server_info = nullptr; |
644 if (quic_server_info_factory_) { | 689 if (quic_server_info_factory_) { |
645 bool load_from_disk_cache = true; | 690 bool load_from_disk_cache = true; |
646 if (http_server_properties_) { | 691 if (http_server_properties_) { |
647 const AlternateProtocolMap& alternate_protocol_map = | 692 const AlternateProtocolMap& alternate_protocol_map = |
648 http_server_properties_->alternate_protocol_map(); | 693 http_server_properties_->alternate_protocol_map(); |
649 AlternateProtocolMap::const_iterator it = | 694 AlternateProtocolMap::const_iterator it = |
650 alternate_protocol_map.Peek(server_id.host_port_pair()); | 695 alternate_protocol_map.Peek(server_id.host_port_pair()); |
651 if (it == alternate_protocol_map.end() || it->second.protocol != QUIC) { | 696 if (it == alternate_protocol_map.end() || it->second.protocol != QUIC) { |
652 // If there is no entry for QUIC, consider that as a new server and | 697 // If there is no entry for QUIC, consider that as a new server and |
653 // don't wait for Cache thread to load the data for that server. | 698 // don't wait for Cache thread to load the data for that server. |
654 load_from_disk_cache = false; | 699 load_from_disk_cache = false; |
655 } | 700 } |
656 } | 701 } |
657 if (load_from_disk_cache) { | 702 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { |
658 QuicCryptoClientConfig::CachedState* cached = | 703 quic_server_info = quic_server_info_factory_->GetForServer(server_id); |
659 crypto_config_.LookupOrCreate(server_id); | |
660 DCHECK(cached); | |
661 if (cached->IsEmpty()) { | |
662 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | |
663 } | |
664 } | 704 } |
665 } | 705 } |
666 // TODO(rtenneti): Initialize task_runner_ in the constructor after | |
667 // WebRequestActionWithThreadsTest.* tests are fixed. | |
668 if (!task_runner_) | |
669 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); | |
670 | 706 |
671 bool was_alternate_protocol_recently_broken = | |
672 http_server_properties_ && | |
673 http_server_properties_->WasAlternateProtocolRecentlyBroken( | |
674 server_id.host_port_pair()); | |
675 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 707 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, |
676 was_alternate_protocol_recently_broken, | 708 WasAlternateProtocolRecentlyBroken(server_id), |
677 privacy_mode, method, quic_server_info, net_log)); | 709 privacy_mode, method == "POST" /* is_post */, |
| 710 quic_server_info, net_log)); |
678 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 711 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
679 base::Unretained(this), job.get())); | 712 base::Unretained(this), job.get())); |
680 | |
681 if (rv == ERR_IO_PENDING) { | 713 if (rv == ERR_IO_PENDING) { |
682 active_requests_[request] = job.get(); | 714 active_requests_[request] = server_id; |
683 job_requests_map_[job.get()].insert(request); | 715 job_requests_map_[server_id].insert(request); |
684 active_jobs_[server_id] = job.release(); | 716 active_jobs_[server_id].insert(job.release()); |
| 717 return rv; |
685 } | 718 } |
686 if (rv == OK) { | 719 if (rv == OK) { |
687 DCHECK(HasActiveSession(server_id)); | 720 DCHECK(HasActiveSession(server_id)); |
688 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 721 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
689 } | 722 } |
690 return rv; | 723 return rv; |
691 } | 724 } |
692 | 725 |
| 726 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, |
| 727 bool is_post, |
| 728 const BoundNetLog& net_log) { |
| 729 Job* aux_job = new Job(this, host_resolver_, server_id.host_port_pair(), |
| 730 server_id.is_https(), |
| 731 WasAlternateProtocolRecentlyBroken(server_id), |
| 732 server_id.privacy_mode(), is_post, nullptr, net_log); |
| 733 active_jobs_[server_id].insert(aux_job); |
| 734 task_runner_->PostTask(FROM_HERE, |
| 735 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, |
| 736 aux_job->GetWeakPtr())); |
| 737 } |
| 738 |
693 bool QuicStreamFactory::OnResolution( | 739 bool QuicStreamFactory::OnResolution( |
694 const QuicServerId& server_id, | 740 const QuicServerId& server_id, |
695 const AddressList& address_list) { | 741 const AddressList& address_list) { |
696 DCHECK(!HasActiveSession(server_id)); | 742 DCHECK(!HasActiveSession(server_id)); |
697 if (disable_connection_pooling_) { | 743 if (disable_connection_pooling_) { |
698 return false; | 744 return false; |
699 } | 745 } |
700 for (const IPEndPoint& address : address_list) { | 746 for (const IPEndPoint& address : address_list) { |
701 const IpAliasKey ip_alias_key(address, server_id.is_https()); | 747 const IpAliasKey ip_alias_key(address, server_id.is_https()); |
702 if (!ContainsKey(ip_aliases_, ip_alias_key)) | 748 if (!ContainsKey(ip_aliases_, ip_alias_key)) |
703 continue; | 749 continue; |
704 | 750 |
705 const SessionSet& sessions = ip_aliases_[ip_alias_key]; | 751 const SessionSet& sessions = ip_aliases_[ip_alias_key]; |
706 for (QuicClientSession* session : sessions) { | 752 for (QuicClientSession* session : sessions) { |
707 if (!session->CanPool(server_id.host(), server_id.privacy_mode())) | 753 if (!session->CanPool(server_id.host(), server_id.privacy_mode())) |
708 continue; | 754 continue; |
709 active_sessions_[server_id] = session; | 755 active_sessions_[server_id] = session; |
710 session_aliases_[session].insert(server_id); | 756 session_aliases_[session].insert(server_id); |
711 return true; | 757 return true; |
712 } | 758 } |
713 } | 759 } |
714 return false; | 760 return false; |
715 } | 761 } |
716 | 762 |
717 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { | 763 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { |
| 764 QuicServerId server_id = job->server_id(); |
| 765 if (rv != OK) { |
| 766 JobSet* jobs = &(active_jobs_[server_id]); |
| 767 if (jobs->size() > 1) { |
| 768 // If there is another pending job, then we can delete this job and let |
| 769 // the other job handle the request. |
| 770 job->Cancel(); |
| 771 jobs->erase(job); |
| 772 delete job; |
| 773 return; |
| 774 } |
| 775 } |
| 776 |
718 if (rv == OK) { | 777 if (rv == OK) { |
719 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 778 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
720 tracked_objects::ScopedTracker tracking_profile1( | 779 tracked_objects::ScopedTracker tracking_profile1( |
721 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 780 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
722 "422516 QuicStreamFactory::OnJobComplete1")); | 781 "422516 QuicStreamFactory::OnJobComplete1")); |
723 | 782 |
724 if (!always_require_handshake_confirmation_) | 783 if (!always_require_handshake_confirmation_) |
725 set_require_confirmation(false); | 784 set_require_confirmation(false); |
726 | 785 |
727 // Create all the streams, but do not notify them yet. | 786 // Create all the streams, but do not notify them yet. |
728 for (RequestSet::iterator it = job_requests_map_[job].begin(); | 787 for (QuicStreamRequest* request : job_requests_map_[server_id]) { |
729 it != job_requests_map_[job].end() ; ++it) { | 788 DCHECK(HasActiveSession(server_id)); |
730 DCHECK(HasActiveSession(job->server_id())); | 789 request->set_stream(CreateIfSessionExists(server_id, request->net_log())); |
731 (*it)->set_stream(CreateIfSessionExists(job->server_id(), | |
732 (*it)->net_log())); | |
733 } | 790 } |
734 } | 791 } |
735 | 792 |
736 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 793 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
737 tracked_objects::ScopedTracker tracking_profile2( | 794 tracked_objects::ScopedTracker tracking_profile2( |
738 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 795 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
739 "422516 QuicStreamFactory::OnJobComplete2")); | 796 "422516 QuicStreamFactory::OnJobComplete2")); |
740 | 797 |
741 while (!job_requests_map_[job].empty()) { | 798 while (!job_requests_map_[server_id].empty()) { |
742 RequestSet::iterator it = job_requests_map_[job].begin(); | 799 RequestSet::iterator it = job_requests_map_[server_id].begin(); |
743 QuicStreamRequest* request = *it; | 800 QuicStreamRequest* request = *it; |
744 job_requests_map_[job].erase(it); | 801 job_requests_map_[server_id].erase(it); |
745 active_requests_.erase(request); | 802 active_requests_.erase(request); |
746 // Even though we're invoking callbacks here, we don't need to worry | 803 // Even though we're invoking callbacks here, we don't need to worry |
747 // about |this| being deleted, because the factory is owned by the | 804 // about |this| being deleted, because the factory is owned by the |
748 // profile which can not be deleted via callbacks. | 805 // profile which can not be deleted via callbacks. |
749 request->OnRequestComplete(rv); | 806 request->OnRequestComplete(rv); |
750 } | 807 } |
751 | 808 |
752 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 809 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
753 tracked_objects::ScopedTracker tracking_profile3( | 810 tracked_objects::ScopedTracker tracking_profile3( |
754 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 811 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
755 "422516 QuicStreamFactory::OnJobComplete3")); | 812 "422516 QuicStreamFactory::OnJobComplete3")); |
756 | 813 |
757 active_jobs_.erase(job->server_id()); | 814 for (Job* other_job : active_jobs_[server_id]) { |
758 job_requests_map_.erase(job); | 815 if (other_job != job) |
759 delete job; | 816 other_job->Cancel(); |
760 return; | 817 } |
| 818 |
| 819 STLDeleteElements(&(active_jobs_[server_id])); |
| 820 active_jobs_.erase(server_id); |
| 821 job_requests_map_.erase(server_id); |
761 } | 822 } |
762 | 823 |
763 // Returns a newly created QuicHttpStream owned by the caller, if a | 824 // Returns a newly created QuicHttpStream owned by the caller, if a |
764 // matching session already exists. Returns nullptr otherwise. | 825 // matching session already exists. Returns nullptr otherwise. |
765 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( | 826 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( |
766 const QuicServerId& server_id, | 827 const QuicServerId& server_id, |
767 const BoundNetLog& net_log) { | 828 const BoundNetLog& net_log) { |
768 if (!HasActiveSession(server_id)) { | 829 if (!HasActiveSession(server_id)) { |
769 DVLOG(1) << "No active session"; | 830 DVLOG(1) << "No active session"; |
770 return scoped_ptr<QuicHttpStream>(); | 831 return scoped_ptr<QuicHttpStream>(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 | 890 |
830 const IpAliasKey ip_alias_key(session->connection()->peer_address(), | 891 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
831 aliases.begin()->is_https()); | 892 aliases.begin()->is_https()); |
832 ip_aliases_[ip_alias_key].erase(session); | 893 ip_aliases_[ip_alias_key].erase(session); |
833 if (ip_aliases_[ip_alias_key].empty()) { | 894 if (ip_aliases_[ip_alias_key].empty()) { |
834 ip_aliases_.erase(ip_alias_key); | 895 ip_aliases_.erase(ip_alias_key); |
835 } | 896 } |
836 QuicServerId server_id = *aliases.begin(); | 897 QuicServerId server_id = *aliases.begin(); |
837 session_aliases_.erase(session); | 898 session_aliases_.erase(session); |
838 Job* job = new Job(this, host_resolver_, session, server_id); | 899 Job* job = new Job(this, host_resolver_, session, server_id); |
839 active_jobs_[server_id] = job; | 900 active_jobs_[server_id].insert(job); |
840 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 901 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
841 base::Unretained(this), job)); | 902 base::Unretained(this), job)); |
842 DCHECK_EQ(ERR_IO_PENDING, rv); | 903 DCHECK_EQ(ERR_IO_PENDING, rv); |
843 } | 904 } |
844 | 905 |
845 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { | 906 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { |
846 DCHECK(ContainsKey(active_requests_, request)); | 907 DCHECK(ContainsKey(active_requests_, request)); |
847 Job* job = active_requests_[request]; | 908 QuicServerId server_id = active_requests_[request]; |
848 job_requests_map_[job].erase(request); | 909 job_requests_map_[server_id].erase(request); |
849 active_requests_.erase(request); | 910 active_requests_.erase(request); |
850 } | 911 } |
851 | 912 |
852 void QuicStreamFactory::CloseAllSessions(int error) { | 913 void QuicStreamFactory::CloseAllSessions(int error) { |
853 while (!active_sessions_.empty()) { | 914 while (!active_sessions_.empty()) { |
854 size_t initial_size = active_sessions_.size(); | 915 size_t initial_size = active_sessions_.size(); |
855 active_sessions_.begin()->second->CloseSessionOnError(error); | 916 active_sessions_.begin()->second->CloseSessionOnError(error); |
856 DCHECK_NE(initial_size, active_sessions_.size()); | 917 DCHECK_NE(initial_size, active_sessions_.size()); |
857 } | 918 } |
858 while (!all_sessions_.empty()) { | 919 while (!all_sessions_.empty()) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 // kind of change it is, we have to flush the socket | 969 // kind of change it is, we have to flush the socket |
909 // pools to be safe. | 970 // pools to be safe. |
910 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 971 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
911 } | 972 } |
912 | 973 |
913 bool QuicStreamFactory::HasActiveSession( | 974 bool QuicStreamFactory::HasActiveSession( |
914 const QuicServerId& server_id) const { | 975 const QuicServerId& server_id) const { |
915 return ContainsKey(active_sessions_, server_id); | 976 return ContainsKey(active_sessions_, server_id); |
916 } | 977 } |
917 | 978 |
| 979 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { |
| 980 return ContainsKey(active_jobs_, key); |
| 981 } |
| 982 |
918 int QuicStreamFactory::CreateSession( | 983 int QuicStreamFactory::CreateSession( |
919 const QuicServerId& server_id, | 984 const QuicServerId& server_id, |
920 scoped_ptr<QuicServerInfo> server_info, | 985 scoped_ptr<QuicServerInfo> server_info, |
921 const AddressList& address_list, | 986 const AddressList& address_list, |
922 const BoundNetLog& net_log, | 987 const BoundNetLog& net_log, |
923 QuicClientSession** session) { | 988 QuicClientSession** session) { |
924 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 989 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
925 tracked_objects::ScopedTracker tracking_profile1( | 990 tracked_objects::ScopedTracker tracking_profile1( |
926 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 991 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
927 "422516 QuicStreamFactory::CreateSession1")); | 992 "422516 QuicStreamFactory::CreateSession1")); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 DCHECK_LE(1u, port_suggester->call_count()); | 1036 DCHECK_LE(1u, port_suggester->call_count()); |
972 } else { | 1037 } else { |
973 DCHECK_EQ(0u, port_suggester->call_count()); | 1038 DCHECK_EQ(0u, port_suggester->call_count()); |
974 } | 1039 } |
975 | 1040 |
976 // We should adaptively set this buffer size, but for now, we'll use a size | 1041 // We should adaptively set this buffer size, but for now, we'll use a size |
977 // that is more than large enough for a full receive window, and yet | 1042 // that is more than large enough for a full receive window, and yet |
978 // does not consume "too much" memory. If we see bursty packet loss, we may | 1043 // does not consume "too much" memory. If we see bursty packet loss, we may |
979 // revisit this setting and test for its impact. | 1044 // revisit this setting and test for its impact. |
980 const int32 kSocketBufferSize = | 1045 const int32 kSocketBufferSize = |
981 static_cast<int32>(TcpReceiver::kReceiveWindowTCP); | 1046 static_cast<int32>(kDefaultSocketReceiveBuffer); |
982 rv = socket->SetReceiveBufferSize(kSocketBufferSize); | 1047 rv = socket->SetReceiveBufferSize(kSocketBufferSize); |
983 if (rv != OK) { | 1048 if (rv != OK) { |
984 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER); | 1049 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER); |
985 return rv; | 1050 return rv; |
986 } | 1051 } |
987 // Set a buffer large enough to contain the initial CWND's worth of packet | 1052 // Set a buffer large enough to contain the initial CWND's worth of packet |
988 // to work around the problem with CHLO packets being sent out with the | 1053 // to work around the problem with CHLO packets being sent out with the |
989 // wrong encryption level, when the send buffer is full. | 1054 // wrong encryption level, when the send buffer is full. |
990 rv = socket->SetSendBufferSize(kMaxPacketSize * 20); | 1055 rv = socket->SetSendBufferSize(kMaxPacketSize * 20); |
991 if (rv != OK) { | 1056 if (rv != OK) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 "422516 QuicStreamFactory::CreateSession6")); | 1156 "422516 QuicStreamFactory::CreateSession6")); |
1092 | 1157 |
1093 // Start the disk cache loading so that we can persist the newer QUIC server | 1158 // Start the disk cache loading so that we can persist the newer QUIC server |
1094 // information and/or inform the disk cache that we have reused | 1159 // information and/or inform the disk cache that we have reused |
1095 // |server_info|. | 1160 // |server_info|. |
1096 server_info.reset(quic_server_info_factory_->GetForServer(server_id)); | 1161 server_info.reset(quic_server_info_factory_->GetForServer(server_id)); |
1097 server_info->Start(); | 1162 server_info->Start(); |
1098 } | 1163 } |
1099 | 1164 |
1100 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1165 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
1101 tracked_objects::ScopedTracker tracking_profile6( | 1166 tracked_objects::ScopedTracker tracking_profile61( |
1102 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1167 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1103 "422516 QuicStreamFactory::CreateSession61")); | 1168 "422516 QuicStreamFactory::CreateSession61")); |
1104 | 1169 |
1105 *session = new QuicClientSession( | 1170 *session = new QuicClientSession( |
1106 connection, socket.Pass(), this, transport_security_state_, | 1171 connection, socket.Pass(), this, transport_security_state_, |
1107 server_info.Pass(), config, | 1172 server_info.Pass(), config, |
1108 base::MessageLoop::current()->message_loop_proxy().get(), | 1173 base::MessageLoop::current()->message_loop_proxy().get(), |
1109 net_log.net_log()); | 1174 net_log.net_log()); |
| 1175 |
| 1176 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1177 tracked_objects::ScopedTracker tracking_profile62( |
| 1178 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1179 "422516 QuicStreamFactory::CreateSession62")); |
| 1180 |
1110 all_sessions_[*session] = server_id; // owning pointer | 1181 all_sessions_[*session] = server_id; // owning pointer |
1111 | 1182 |
1112 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1183 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
1113 tracked_objects::ScopedTracker tracking_profile7( | 1184 tracked_objects::ScopedTracker tracking_profile7( |
1114 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1185 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1115 "422516 QuicStreamFactory::CreateSession7")); | 1186 "422516 QuicStreamFactory::CreateSession7")); |
1116 | 1187 |
1117 (*session)->InitializeSession(server_id, &crypto_config_, | 1188 (*session)->InitializeSession(server_id, &crypto_config_, |
1118 quic_crypto_client_stream_factory_); | 1189 quic_crypto_client_stream_factory_); |
1119 bool closed_during_initialize = | 1190 bool closed_during_initialize = |
1120 !ContainsKey(all_sessions_, *session) || | 1191 !ContainsKey(all_sessions_, *session) || |
1121 !(*session)->connection()->connected(); | 1192 !(*session)->connection()->connected(); |
1122 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession", | 1193 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession", |
1123 closed_during_initialize); | 1194 closed_during_initialize); |
1124 if (closed_during_initialize) { | 1195 if (closed_during_initialize) { |
1125 DLOG(DFATAL) << "Session closed during initialize"; | 1196 DLOG(DFATAL) << "Session closed during initialize"; |
1126 *session = nullptr; | 1197 *session = nullptr; |
1127 return ERR_CONNECTION_CLOSED; | 1198 return ERR_CONNECTION_CLOSED; |
1128 } | 1199 } |
1129 return OK; | 1200 return OK; |
1130 } | 1201 } |
1131 | 1202 |
1132 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | |
1133 return ContainsKey(active_jobs_, key); | |
1134 } | |
1135 | |
1136 void QuicStreamFactory::ActivateSession( | 1203 void QuicStreamFactory::ActivateSession( |
1137 const QuicServerId& server_id, | 1204 const QuicServerId& server_id, |
1138 QuicClientSession* session) { | 1205 QuicClientSession* session) { |
1139 DCHECK(!HasActiveSession(server_id)); | 1206 DCHECK(!HasActiveSession(server_id)); |
1140 UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size()); | 1207 UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size()); |
1141 active_sessions_[server_id] = session; | 1208 active_sessions_[server_id] = session; |
1142 session_aliases_[session].insert(server_id); | 1209 session_aliases_[session].insert(server_id); |
1143 const IpAliasKey ip_alias_key(session->connection()->peer_address(), | 1210 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
1144 server_id.is_https()); | 1211 server_id.is_https()); |
1145 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); | 1212 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); |
1146 ip_aliases_[ip_alias_key].insert(session); | 1213 ip_aliases_[ip_alias_key].insert(session); |
1147 } | 1214 } |
1148 | 1215 |
1149 int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( | 1216 int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( |
1150 const QuicServerId& server_id) const { | 1217 const QuicServerId& server_id) const { |
1151 if (!http_server_properties_) | 1218 if (!http_server_properties_) |
1152 return 0; | 1219 return 0; |
1153 const ServerNetworkStats* stats = | 1220 const ServerNetworkStats* stats = |
1154 http_server_properties_->GetServerNetworkStats( | 1221 http_server_properties_->GetServerNetworkStats( |
1155 server_id.host_port_pair()); | 1222 server_id.host_port_pair()); |
1156 if (stats == nullptr) | 1223 if (stats == nullptr) |
1157 return 0; | 1224 return 0; |
1158 return stats->srtt.InMicroseconds(); | 1225 return stats->srtt.InMicroseconds(); |
1159 } | 1226 } |
1160 | 1227 |
| 1228 bool QuicStreamFactory::WasAlternateProtocolRecentlyBroken( |
| 1229 const QuicServerId& server_id) const { |
| 1230 return http_server_properties_ && |
| 1231 http_server_properties_->WasAlternateProtocolRecentlyBroken( |
| 1232 server_id.host_port_pair()); |
| 1233 } |
| 1234 |
| 1235 bool QuicStreamFactory::CryptoConfigCacheIsEmpty( |
| 1236 const QuicServerId& server_id) { |
| 1237 QuicCryptoClientConfig::CachedState* cached = |
| 1238 crypto_config_.LookupOrCreate(server_id); |
| 1239 return cached->IsEmpty(); |
| 1240 } |
| 1241 |
1161 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( | 1242 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( |
1162 const QuicServerId& server_id, | 1243 const QuicServerId& server_id, |
1163 const scoped_ptr<QuicServerInfo>& server_info) { | 1244 const scoped_ptr<QuicServerInfo>& server_info) { |
1164 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1245 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
1165 tracked_objects::ScopedTracker tracking_profile1( | 1246 tracked_objects::ScopedTracker tracking_profile1( |
1166 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1247 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1167 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); | 1248 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); |
1168 | 1249 |
1169 // |server_info| will be NULL, if a non-empty server config already exists in | 1250 // |server_info| will be NULL, if a non-empty server config already exists in |
1170 // the memory cache. This is a minor optimization to avoid LookupOrCreate. | 1251 // the memory cache. This is a minor optimization to avoid LookupOrCreate. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 http_server_properties_->ClearAlternateProtocol(server); | 1345 http_server_properties_->ClearAlternateProtocol(server); |
1265 http_server_properties_->SetAlternateProtocol( | 1346 http_server_properties_->SetAlternateProtocol( |
1266 server, alternate.port, alternate.protocol, 1); | 1347 server, alternate.port, alternate.protocol, 1); |
1267 DCHECK_EQ(QUIC, | 1348 DCHECK_EQ(QUIC, |
1268 http_server_properties_->GetAlternateProtocol(server).protocol); | 1349 http_server_properties_->GetAlternateProtocol(server).protocol); |
1269 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( | 1350 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( |
1270 server)); | 1351 server)); |
1271 } | 1352 } |
1272 | 1353 |
1273 } // namespace net | 1354 } // namespace net |
OLD | NEW |