Chromium Code Reviews| 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 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 active_requests_[request] = server_id; | 680 active_requests_[request] = server_id; |
| 681 job_requests_map_[server_id].insert(request); | 681 job_requests_map_[server_id].insert(request); |
| 682 return ERR_IO_PENDING; | 682 return ERR_IO_PENDING; |
| 683 } | 683 } |
| 684 | 684 |
| 685 // TODO(rtenneti): |task_runner_| is used by the Job. Initialize task_runner_ | 685 // TODO(rtenneti): |task_runner_| is used by the Job. Initialize task_runner_ |
| 686 // in the constructor after WebRequestActionWithThreadsTest.* tests are fixed. | 686 // in the constructor after WebRequestActionWithThreadsTest.* tests are fixed. |
| 687 if (!task_runner_) | 687 if (!task_runner_) |
| 688 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); | 688 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); |
| 689 | 689 |
| 690 QuicServerInfo* quic_server_info = nullptr; | 690 bool was_alternate_protocol_recently_broken = false; |
| 691 if (quic_server_info_factory_) { | 691 bool load_from_disk_cache = !disable_disk_cache_; |
| 692 bool load_from_disk_cache = !disable_disk_cache_; | 692 if (http_server_properties_) { |
| 693 if (http_server_properties_) { | 693 const AlternateProtocolMap& alternate_protocol_map = |
| 694 const AlternateProtocolMap& alternate_protocol_map = | 694 http_server_properties_->alternate_protocol_map(); |
| 695 http_server_properties_->alternate_protocol_map(); | 695 AlternateProtocolMap::const_iterator it = |
| 696 AlternateProtocolMap::const_iterator it = | 696 alternate_protocol_map.Peek(server_id.host_port_pair()); |
| 697 alternate_protocol_map.Peek(server_id.host_port_pair()); | 697 // If there is no entry for QUIC, consider that as a new server and |
| 698 if (it == alternate_protocol_map.end() || it->second.protocol != QUIC) { | 698 // don't wait for Cache thread to load the data for that server. |
| 699 // If there is no entry for QUIC, consider that as a new server and | 699 if (it == alternate_protocol_map.end()) { |
| 700 // don't wait for Cache thread to load the data for that server. | 700 load_from_disk_cache = false; |
| 701 } else { | |
| 702 AlternateProtocols alternate_protocols = it->second; | |
| 703 AlternateProtocols::iterator alternate; | |
| 704 for (alternate = alternate_protocols.begin(); | |
| 705 alternate != alternate_protocols.end(); ++alternate) { | |
| 706 if (alternate->protocol == QUIC) { | |
| 707 was_alternate_protocol_recently_broken = | |
| 708 WasAlternateProtocolRecentlyBroken(server_id, *alternate); | |
| 709 break; | |
| 710 } | |
| 711 } | |
| 712 if (alternate == alternate_protocols.end()) { | |
| 701 load_from_disk_cache = false; | 713 load_from_disk_cache = false; |
| 702 } | 714 } |
| 703 } | 715 } |
| 704 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { | 716 } |
|
Ryan Hamilton
2015/02/27 18:20:48
There's a lot going on here, I think it might make
Bence
2015/02/27 19:31:41
Can I do that later? A lot of things will change
| |
| 705 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | 717 |
| 706 } | 718 QuicServerInfo* quic_server_info = nullptr; |
| 719 if (quic_server_info_factory_ && load_from_disk_cache && | |
| 720 CryptoConfigCacheIsEmpty(server_id)) { | |
| 721 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | |
| 707 } | 722 } |
| 708 | 723 |
| 709 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 724 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, |
| 710 WasAlternateProtocolRecentlyBroken(server_id), | 725 was_alternate_protocol_recently_broken, |
| 711 privacy_mode, method == "POST" /* is_post */, | 726 privacy_mode, method == "POST" /* is_post */, |
| 712 quic_server_info, net_log)); | 727 quic_server_info, net_log)); |
| 713 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 728 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 714 base::Unretained(this), job.get())); | 729 base::Unretained(this), job.get())); |
| 715 if (rv == ERR_IO_PENDING) { | 730 if (rv == ERR_IO_PENDING) { |
| 716 active_requests_[request] = server_id; | 731 active_requests_[request] = server_id; |
| 717 job_requests_map_[server_id].insert(request); | 732 job_requests_map_[server_id].insert(request); |
| 718 active_jobs_[server_id].insert(job.release()); | 733 active_jobs_[server_id].insert(job.release()); |
| 719 return rv; | 734 return rv; |
| 720 } | 735 } |
| 721 if (rv == OK) { | 736 if (rv == OK) { |
| 722 DCHECK(HasActiveSession(server_id)); | 737 DCHECK(HasActiveSession(server_id)); |
| 723 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 738 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
| 724 } | 739 } |
| 725 return rv; | 740 return rv; |
| 726 } | 741 } |
| 727 | 742 |
| 728 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, | 743 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, |
| 729 bool is_post, | 744 bool is_post, |
| 730 const BoundNetLog& net_log) { | 745 const BoundNetLog& net_log) { |
| 731 Job* aux_job = new Job(this, host_resolver_, server_id.host_port_pair(), | 746 const AlternateProtocolInfo alternate_protocol(server_id.port(), QUIC, 0.0); |
|
Ryan Hamilton
2015/02/27 18:20:48
It seems like this should be done *in* WasAlternat
Bence
2015/02/27 19:31:41
I think this just underlines the issue that we nee
| |
| 732 server_id.is_https(), | 747 Job* aux_job = new Job( |
| 733 WasAlternateProtocolRecentlyBroken(server_id), | 748 this, host_resolver_, server_id.host_port_pair(), server_id.is_https(), |
| 734 server_id.privacy_mode(), is_post, nullptr, net_log); | 749 WasAlternateProtocolRecentlyBroken(server_id, alternate_protocol), |
| 750 server_id.privacy_mode(), is_post, nullptr, net_log); | |
| 735 active_jobs_[server_id].insert(aux_job); | 751 active_jobs_[server_id].insert(aux_job); |
| 736 task_runner_->PostTask(FROM_HERE, | 752 task_runner_->PostTask(FROM_HERE, |
| 737 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, | 753 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, |
| 738 aux_job->GetWeakPtr())); | 754 aux_job->GetWeakPtr())); |
| 739 } | 755 } |
| 740 | 756 |
| 741 bool QuicStreamFactory::OnResolution( | 757 bool QuicStreamFactory::OnResolution( |
| 742 const QuicServerId& server_id, | 758 const QuicServerId& server_id, |
| 743 const AddressList& address_list) { | 759 const AddressList& address_list) { |
| 744 DCHECK(!HasActiveSession(server_id)); | 760 DCHECK(!HasActiveSession(server_id)); |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1221 return 0; | 1237 return 0; |
| 1222 const ServerNetworkStats* stats = | 1238 const ServerNetworkStats* stats = |
| 1223 http_server_properties_->GetServerNetworkStats( | 1239 http_server_properties_->GetServerNetworkStats( |
| 1224 server_id.host_port_pair()); | 1240 server_id.host_port_pair()); |
| 1225 if (stats == nullptr) | 1241 if (stats == nullptr) |
| 1226 return 0; | 1242 return 0; |
| 1227 return stats->srtt.InMicroseconds(); | 1243 return stats->srtt.InMicroseconds(); |
| 1228 } | 1244 } |
| 1229 | 1245 |
| 1230 bool QuicStreamFactory::WasAlternateProtocolRecentlyBroken( | 1246 bool QuicStreamFactory::WasAlternateProtocolRecentlyBroken( |
| 1231 const QuicServerId& server_id) const { | 1247 const QuicServerId& server_id, |
| 1248 const AlternateProtocolInfo& alternate_protocol) const { | |
| 1232 return http_server_properties_ && | 1249 return http_server_properties_ && |
| 1233 http_server_properties_->WasAlternateProtocolRecentlyBroken( | 1250 http_server_properties_->WasAlternateProtocolRecentlyBroken( |
| 1234 server_id.host_port_pair()); | 1251 server_id.host_port_pair(), alternate_protocol); |
| 1235 } | 1252 } |
| 1236 | 1253 |
| 1237 bool QuicStreamFactory::CryptoConfigCacheIsEmpty( | 1254 bool QuicStreamFactory::CryptoConfigCacheIsEmpty( |
| 1238 const QuicServerId& server_id) { | 1255 const QuicServerId& server_id) { |
| 1239 QuicCryptoClientConfig::CachedState* cached = | 1256 QuicCryptoClientConfig::CachedState* cached = |
| 1240 crypto_config_.LookupOrCreate(server_id); | 1257 crypto_config_.LookupOrCreate(server_id); |
| 1241 return cached->IsEmpty(); | 1258 return cached->IsEmpty(); |
| 1242 } | 1259 } |
| 1243 | 1260 |
| 1244 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( | 1261 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( |
| 1245 const QuicServerId& server_id, | 1262 const QuicServerId& server_id, |
| 1246 const scoped_ptr<QuicServerInfo>& server_info) { | 1263 const scoped_ptr<QuicServerInfo>& server_info) { |
| 1247 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1264 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1248 tracked_objects::ScopedTracker tracking_profile1( | 1265 tracked_objects::ScopedTracker tracking_profile1( |
| 1249 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1266 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1250 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); | 1267 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); |
| 1251 | 1268 |
| 1252 // |server_info| will be NULL, if a non-empty server config already exists in | 1269 // |server_info| will be NULL, if a non-empty server config already exists in |
| 1253 // the memory cache. This is a minor optimization to avoid LookupOrCreate. | 1270 // the memory cache. This is a minor optimization to avoid LookupOrCreate. |
| 1254 if (!server_info) | 1271 if (!server_info) |
| 1255 return; | 1272 return; |
| 1256 | 1273 |
| 1257 QuicCryptoClientConfig::CachedState* cached = | 1274 QuicCryptoClientConfig::CachedState* cached = |
| 1258 crypto_config_.LookupOrCreate(server_id); | 1275 crypto_config_.LookupOrCreate(server_id); |
| 1259 if (!cached->IsEmpty()) | 1276 if (!cached->IsEmpty()) |
| 1260 return; | 1277 return; |
| 1261 | 1278 |
| 1262 if (http_server_properties_) { | 1279 if (http_server_properties_) { |
| 1263 if (quic_supported_servers_at_startup_.empty()) { | 1280 if (quic_supported_servers_at_startup_.empty()) { |
| 1264 for (const std::pair<const HostPortPair, AlternateProtocolInfo>& | 1281 for (const std::pair<const HostPortPair, AlternateProtocols>& key_value : |
| 1265 key_value : http_server_properties_->alternate_protocol_map()) { | 1282 http_server_properties_->alternate_protocol_map()) { |
| 1266 if (key_value.second.protocol == QUIC) { | 1283 for (const AlternateProtocolInfo& alternate_protocol : |
| 1267 quic_supported_servers_at_startup_.insert(key_value.first); | 1284 key_value.second) { |
| 1285 if (alternate_protocol.protocol == QUIC) { | |
| 1286 quic_supported_servers_at_startup_.insert(key_value.first); | |
| 1287 break; | |
| 1288 } | |
| 1268 } | 1289 } |
| 1269 } | 1290 } |
| 1270 } | 1291 } |
| 1271 | 1292 |
| 1272 // TODO(rtenneti): Delete the following histogram after collecting stats. | 1293 // TODO(rtenneti): Delete the following histogram after collecting stats. |
| 1273 // If the AlternateProtocolMap contained an entry for this host, check if | 1294 // If the AlternateProtocolMap contained an entry for this host, check if |
| 1274 // the disk cache contained an entry for it. | 1295 // the disk cache contained an entry for it. |
| 1275 if (ContainsKey(quic_supported_servers_at_startup_, | 1296 if (ContainsKey(quic_supported_servers_at_startup_, |
| 1276 server_id.host_port_pair())) { | 1297 server_id.host_port_pair())) { |
| 1277 UMA_HISTOGRAM_BOOLEAN( | 1298 UMA_HISTOGRAM_BOOLEAN( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1314 network_stats); | 1335 network_stats); |
| 1315 return; | 1336 return; |
| 1316 } | 1337 } |
| 1317 | 1338 |
| 1318 UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived", | 1339 UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived", |
| 1319 stats.packets_received); | 1340 stats.packets_received); |
| 1320 | 1341 |
| 1321 if (!session_was_active) | 1342 if (!session_was_active) |
| 1322 return; | 1343 return; |
| 1323 | 1344 |
| 1345 // A QUIC alternate job was started iff there is a non-broken QUIC alternate | |
| 1346 // protocol for the server. | |
|
Ryan Hamilton
2015/02/27 18:20:48
I don't understand this comment.
Bence
2015/02/27 19:31:41
I am substituting new lines 1350--1359 for old lin
| |
| 1324 const HostPortPair& server = server_id.host_port_pair(); | 1347 const HostPortPair& server = server_id.host_port_pair(); |
| 1325 // Don't try to change the alternate-protocol state, if the | 1348 const AlternateProtocols alternate_protocols = |
| 1326 // alternate-protocol state is unknown. | 1349 http_server_properties_->GetAlternateProtocols(server); |
| 1327 const AlternateProtocolInfo alternate = | 1350 AlternateProtocols::const_iterator alternate; |
| 1328 http_server_properties_->GetAlternateProtocol(server); | 1351 for (alternate = alternate_protocols.begin(); |
|
Ryan Hamilton
2015/02/27 18:20:48
range-base for loop, please.
Bence
2015/02/27 19:31:41
Note that in this case I couldn't do it, because r
| |
| 1329 if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 1352 alternate != alternate_protocols.end(); ++alternate) { |
| 1353 if (!alternate->is_broken && alternate->protocol == QUIC) { | |
| 1354 break; | |
| 1355 } | |
| 1356 } | |
| 1357 if (alternate == alternate_protocols.end()) { | |
| 1330 return; | 1358 return; |
| 1359 } | |
|
Ryan Hamilton
2015/02/27 18:20:48
As per the design doc you wrote up, I think this c
Bence
2015/02/27 19:31:41
Absolutely. Let's revisit this once we work out t
| |
| 1331 | 1360 |
| 1332 // TODO(rch): In the special case where the session has received no | 1361 // TODO(rch): In the special case where the session has received no |
| 1333 // packets from the peer, we should consider blacklisting this | 1362 // packets from the peer, we should consider blacklisting this |
| 1334 // differently so that we still race TCP but we don't consider the | 1363 // differently so that we still race TCP but we don't consider the |
| 1335 // session connected until the handshake has been confirmed. | 1364 // session connected until the handshake has been confirmed. |
| 1336 HistogramBrokenAlternateProtocolLocation( | 1365 HistogramBrokenAlternateProtocolLocation( |
| 1337 BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_STREAM_FACTORY); | 1366 BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_STREAM_FACTORY); |
| 1338 DCHECK_EQ(QUIC, alternate.protocol); | |
| 1339 | 1367 |
| 1340 // Since the session was active, there's no longer an | 1368 // Since the session was active, there's no longer an |
| 1341 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the | 1369 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the |
| 1342 // TCP job also fails. So to avoid not using QUIC when we otherwise could, | 1370 // TCP job also fails. So to avoid not using QUIC when we otherwise could, |
| 1343 // we mark it as broken, and then immediately re-enable it. This leaves | 1371 // we mark it as broken, and then immediately re-enable it. This leaves |
| 1344 // QUIC as "recently broken" which means that 0-RTT will be disabled but | 1372 // QUIC as "recently broken" which means that 0-RTT will be disabled but |
| 1345 // we'll still race. | 1373 // we'll still race. |
| 1346 http_server_properties_->SetBrokenAlternateProtocol(server); | 1374 http_server_properties_->SetBrokenAlternateProtocol(server, *alternate); |
| 1347 http_server_properties_->ClearAlternateProtocol(server); | 1375 http_server_properties_->RemoveAlternateProtocol(server, *alternate); |
| 1348 http_server_properties_->SetAlternateProtocol( | 1376 http_server_properties_->AddAlternateProtocol(server, alternate->port, |
| 1349 server, alternate.port, alternate.protocol, 1); | 1377 alternate->protocol, 1); |
| 1350 DCHECK_EQ(QUIC, | |
| 1351 http_server_properties_->GetAlternateProtocol(server).protocol); | |
| 1352 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( | 1378 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( |
| 1353 server)); | 1379 server, *alternate)); |
| 1354 } | 1380 } |
| 1355 | 1381 |
| 1356 } // namespace net | 1382 } // namespace net |
| OLD | NEW |