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 <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 #endif | 49 #endif |
50 | 50 |
51 #if defined(USE_OPENSSL) | 51 #if defined(USE_OPENSSL) |
52 #include <openssl/aead.h> | 52 #include <openssl/aead.h> |
53 #include "crypto/openssl_util.h" | 53 #include "crypto/openssl_util.h" |
54 #else | 54 #else |
55 #include "base/cpu.h" | 55 #include "base/cpu.h" |
56 #endif | 56 #endif |
57 | 57 |
58 using std::min; | 58 using std::min; |
59 using NetworkChangeNotifier::NetworkHandle; | |
59 | 60 |
60 namespace net { | 61 namespace net { |
61 | 62 |
62 namespace { | 63 namespace { |
63 | 64 |
64 enum CreateSessionFailure { | 65 enum CreateSessionFailure { |
65 CREATION_ERROR_CONNECTING_SOCKET, | 66 CREATION_ERROR_CONNECTING_SOCKET, |
66 CREATION_ERROR_SETTING_RECEIVE_BUFFER, | 67 CREATION_ERROR_SETTING_RECEIVE_BUFFER, |
67 CREATION_ERROR_SETTING_SEND_BUFFER, | 68 CREATION_ERROR_SETTING_SEND_BUFFER, |
68 CREATION_ERROR_MAX | 69 CREATION_ERROR_MAX |
69 }; | 70 }; |
70 | 71 |
71 // When a connection is idle for 30 seconds it will be closed. | 72 // When a connection is idle for 30 seconds it will be closed. |
72 const int kIdleConnectionTimeoutSeconds = 30; | 73 const int kIdleConnectionTimeoutSeconds = 30; |
73 | 74 |
74 // The maximum receive window sizes for QUIC sessions and streams. | 75 // The maximum receive window sizes for QUIC sessions and streams. |
75 const int32 kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB | 76 const int32 kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB |
76 const int32 kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB | 77 const int32 kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB |
77 | 78 |
78 // Set the maximum number of undecryptable packets the connection will store. | 79 // Set the maximum number of undecryptable packets the connection will store. |
79 const int32 kMaxUndecryptablePackets = 100; | 80 const int32 kMaxUndecryptablePackets = 100; |
80 | 81 |
82 // A default NetworkHandle. | |
83 const NetworkHandle kDefaultNetworkHandle = -2; | |
pauljensen
2015/10/14 11:51:34
This is a little sketchy for my liking. I'd sugge
Jana
2015/10/16 23:11:00
I think this is all sketchy :-) But, yeah, it seem
| |
84 | |
81 void HistogramCreateSessionFailure(enum CreateSessionFailure error) { | 85 void HistogramCreateSessionFailure(enum CreateSessionFailure error) { |
82 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error, | 86 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error, |
83 CREATION_ERROR_MAX); | 87 CREATION_ERROR_MAX); |
84 } | 88 } |
85 | 89 |
86 bool IsEcdsaSupported() { | 90 bool IsEcdsaSupported() { |
87 #if defined(OS_WIN) | 91 #if defined(OS_WIN) |
88 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 92 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
89 return false; | 93 return false; |
90 #endif | 94 #endif |
(...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1130 list->Append(session->GetInfoAsValue(hosts)); | 1134 list->Append(session->GetInfoAsValue(hosts)); |
1131 } | 1135 } |
1132 } | 1136 } |
1133 return list.Pass(); | 1137 return list.Pass(); |
1134 } | 1138 } |
1135 | 1139 |
1136 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { | 1140 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { |
1137 crypto_config_.ClearCachedStates(); | 1141 crypto_config_.ClearCachedStates(); |
1138 } | 1142 } |
1139 | 1143 |
1144 // We still need OnIPAddressChanged, but not for Android >= L. | |
1145 // pauljensen: How do we do this? | |
pauljensen
2015/10/14 11:51:34
Where do you register for events? (i.e. call Netwo
Jana
2015/10/16 23:11:00
*Facepalm*. So I discovered that we do not actuall
| |
1140 void QuicStreamFactory::OnIPAddressChanged() { | 1146 void QuicStreamFactory::OnIPAddressChanged() { |
1141 CloseAllSessions(ERR_NETWORK_CHANGED); | 1147 CloseAllSessions(ERR_NETWORK_CHANGED); |
1142 set_require_confirmation(true); | 1148 set_require_confirmation(true); |
1143 } | 1149 } |
1144 | 1150 |
1151 void QuicStreamFactory::OnNetworkConnected(NetworkHandle network) { | |
1152 // Nothing to do. | |
1153 } | |
1154 | |
1155 void QuicStreamFactory::OnNetworkMadeDefault(NetworkHandle network) { | |
1156 // Nothing to do. | |
1157 } | |
1158 | |
1159 void QuicStreamFactory::OnNetworkDisconnected(NetworkHandle network) { | |
1160 MigrateOrCloseSessions(network); | |
1161 } | |
1162 | |
1163 void QuicStreamFactory::OnNetworkSoonToDisconnect(NetworkHandle network) { | |
1164 MigrateOrCloseSessions(network); | |
1165 } | |
1166 | |
1167 void QuicStreamFactory::MigrateOrCloseSessions(NetworkHandle network) { | |
1168 // pauljensen: do we need the following "== network" check? | |
pauljensen
2015/10/14 11:51:34
seems like a good idea
Jana
2015/10/16 23:11:00
Acknowledged.
| |
1169 NetworkList network_list; | |
1170 GetConnectedNetworks(&network_list); | |
1171 if (network_list.isEmpty() || | |
1172 (network_list.size() == 1 && network_list[0] == network)) { | |
1173 CloseAllSessions(ERR_NETWORK_CHANGED); | |
1174 set_require_confirmation(true); | |
1175 return; | |
1176 } | |
1177 | |
1178 // Find a new network that old sockets can be migrated to. | |
1179 // pauljensen: do we need the following "== network" check? | |
pauljensen
2015/10/14 11:51:34
seems like a good idea
Jana
2015/10/16 23:11:00
Acknowledged.
| |
1180 NetworkHandle new_network = kInvalidNetworkHandle; | |
1181 for (NetworkHandle n : network_list) { | |
1182 if (n == network) { | |
1183 continue; | |
1184 } | |
1185 new_network = n; | |
1186 } | |
1187 | |
1188 DCHECK_NE(kInvalidNetworkHandle, new_network); | |
1189 DCHECK_NE(network, new_network); | |
1190 | |
1191 for (QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin(); | |
1192 it != all_sessions_.end(); ++it) { | |
1193 QuicChromiumClientSession* session = it->first; | |
1194 QuicServerId server_id = it->second; | |
1195 | |
1196 if (session->GetNumOpenStreams() == 0) { | |
1197 // If idle session, close session | |
1198 active_sessions_.erase(server_id); | |
1199 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); | |
1200 } else if (session->current_network() == new_network) { | |
1201 // @@@ TODO (jri): store network and record in session when | |
1202 // BindToNetwork() is called. | |
1203 // If session is already using |network|, move on. | |
1204 continue; | |
1205 } else { | |
1206 // If session is active, | |
1207 // (i) make the session GO_AWAY, | |
1208 // (ii) create a new socket (which should be bound to the new interface), | |
1209 // (iii) add a new PacketReader to the session to read from new socket, | |
1210 // (iv) replace the connection's PacketWriter with a new PacketWriter | |
1211 // that uses the new socket. | |
1212 set_require_confirmation(true); | |
1213 OnSessionGoingAway(session); | |
1214 scoped_ptr<DatagramClientSocket> socket; | |
1215 int rv = CreateAndConfigureDatagramSocket(&socket, | |
1216 all_sessions[*session], | |
1217 connection->peer_address(), | |
1218 session->net_log(), | |
1219 new_network); | |
1220 if (rv != OK) { | |
1221 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); | |
1222 continue; | |
1223 } | |
1224 | |
1225 if (!session->AddPacketReader(new QuicPacketReader(socket.get(), | |
1226 clock_.get(), | |
1227 session, | |
1228 yield_after_packets_, | |
1229 yield_after_duration_, | |
1230 session->net_log()))) { | |
1231 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); | |
1232 continue; | |
1233 } | |
1234 | |
1235 session->StartReading(); | |
1236 DefaultPacketWriterFactory packet_writer_factory(socket.get()); | |
1237 QuicConnection* connection = session->connection(); | |
1238 connection->SetQuicPacketWriter(packet_writer_factory.Create(connection), | |
1239 /*owns_writer=*/true); | |
1240 | |
1241 session->AddSocket(socket.Pass()); | |
1242 } | |
1243 } | |
1244 } | |
1245 | |
1145 void QuicStreamFactory::OnSSLConfigChanged() { | 1246 void QuicStreamFactory::OnSSLConfigChanged() { |
1146 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 1247 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
1147 } | 1248 } |
1148 | 1249 |
1149 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { | 1250 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { |
1150 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 1251 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
1151 } | 1252 } |
1152 | 1253 |
1153 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { | 1254 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { |
1154 // We should flush the sessions if we removed trust from a | 1255 // We should flush the sessions if we removed trust from a |
(...skipping 10 matching lines...) Expand all Loading... | |
1165 | 1266 |
1166 bool QuicStreamFactory::HasActiveSession( | 1267 bool QuicStreamFactory::HasActiveSession( |
1167 const QuicServerId& server_id) const { | 1268 const QuicServerId& server_id) const { |
1168 return ContainsKey(active_sessions_, server_id); | 1269 return ContainsKey(active_sessions_, server_id); |
1169 } | 1270 } |
1170 | 1271 |
1171 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | 1272 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { |
1172 return ContainsKey(active_jobs_, key); | 1273 return ContainsKey(active_jobs_, key); |
1173 } | 1274 } |
1174 | 1275 |
1175 int QuicStreamFactory::CreateSession(const QuicServerId& server_id, | 1276 int QuicStreamFactory::CreateAndConfigureDatagramSocket( |
1176 int cert_verify_flags, | 1277 scoped_ptr<DatagramClientSocket>* new_socket, |
pauljensen
2015/10/14 11:51:34
http://dev.chromium.org/developers/smart-pointer-g
Jana
2015/10/16 23:11:00
Done.
| |
1177 scoped_ptr<QuicServerInfo> server_info, | 1278 const QuicServerId& server_id, |
1178 const AddressList& address_list, | 1279 IPEndPoint addr, |
1179 base::TimeTicks dns_resolution_end_time, | 1280 const BoundNetLog& net_log, |
1180 const BoundNetLog& net_log, | 1281 NetworkHandle network) { |
1181 QuicChromiumClientSession** session) { | |
1182 bool enable_port_selection = enable_port_selection_; | 1282 bool enable_port_selection = enable_port_selection_; |
1183 if (enable_port_selection && | 1283 if (enable_port_selection && |
1184 ContainsKey(gone_away_aliases_, server_id)) { | 1284 ContainsKey(gone_away_aliases_, server_id)) { |
1185 // Disable port selection when the server is going away. | 1285 // Disable port selection when the server is going away. |
1186 // There is no point in trying to return to the same server, if | 1286 // There is no point in trying to return to the same server, if |
1187 // that server is no longer handling requests. | 1287 // that server is no longer handling requests. |
1188 enable_port_selection = false; | 1288 enable_port_selection = false; |
1189 gone_away_aliases_.erase(server_id); | 1289 gone_away_aliases_.erase(server_id); |
1190 } | 1290 } |
1191 | 1291 |
1192 QuicConnectionId connection_id = random_generator_->RandUint64(); | |
1193 IPEndPoint addr = *address_list.begin(); | |
1194 scoped_refptr<PortSuggester> port_suggester = | 1292 scoped_refptr<PortSuggester> port_suggester = |
1195 new PortSuggester(server_id.host_port_pair(), port_seed_); | 1293 new PortSuggester(server_id.host_port_pair(), port_seed_); |
1196 DatagramSocket::BindType bind_type = enable_port_selection ? | 1294 DatagramSocket::BindType bind_type = enable_port_selection ? |
1197 DatagramSocket::RANDOM_BIND : // Use our callback. | 1295 DatagramSocket::RANDOM_BIND : // Use our callback. |
1198 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 1296 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
1199 scoped_ptr<DatagramClientSocket> socket( | 1297 scoped_ptr<DatagramClientSocket> socket( |
1200 client_socket_factory_->CreateDatagramClientSocket( | 1298 client_socket_factory_->CreateDatagramClientSocket( |
1201 bind_type, | 1299 bind_type, |
1202 base::Bind(&PortSuggester::SuggestPort, port_suggester), | 1300 base::Bind(&PortSuggester::SuggestPort, port_suggester), |
1203 net_log.net_log(), net_log.source())); | 1301 net_log.net_log(), net_log.source())); |
1204 | 1302 |
1205 if (enable_non_blocking_io_ && | 1303 if (enable_non_blocking_io_ && |
1206 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { | 1304 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { |
1207 #if defined(OS_WIN) | 1305 #if defined(OS_WIN) |
1208 static_cast<UDPClientSocket*>(socket.get())->UseNonBlockingIO(); | 1306 static_cast<UDPClientSocket*>(socket.get())->UseNonBlockingIO(); |
1209 #endif | 1307 #endif |
1210 } | 1308 } |
1211 | 1309 |
1212 int rv = socket->Connect(addr); | 1310 // If caller leaves network unspecified, find current default. |
1311 if (network == kDefaultNetworkHandle) { | |
1312 network = NetworkChangeNotifier::GetDefaultNetwork(); | |
pauljensen
2015/10/14 11:51:34
We may want to loop here in cases where the defaul
Jana
2015/10/16 23:11:00
I've added a BindToDefaultNetwork method to Datagr
| |
1313 if (network == kDefaultNetworkHandle) { | |
1314 return ERR_INTERNET_DISCONNECTED; | |
1315 } | |
1316 } | |
1213 | 1317 |
1318 new_socket->Reset(socket.get()); | |
1319 | |
1320 int rv = socket->BindToNetwork(network); | |
1321 if (rv != OK) { | |
1322 return rv; | |
1323 } | |
1324 | |
1325 rv = socket->Connect(addr); | |
1214 if (rv != OK) { | 1326 if (rv != OK) { |
1215 HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET); | 1327 HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET); |
1216 return rv; | 1328 return rv; |
1217 } | 1329 } |
1218 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested", | 1330 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested", |
1219 port_suggester->call_count()); | 1331 port_suggester->call_count()); |
1220 if (enable_port_selection) { | 1332 if (enable_port_selection) { |
1221 DCHECK_LE(1u, port_suggester->call_count()); | 1333 DCHECK_LE(1u, port_suggester->call_count()); |
1222 } else { | 1334 } else { |
1223 DCHECK_EQ(0u, port_suggester->call_count()); | 1335 DCHECK_EQ(0u, port_suggester->call_count()); |
(...skipping 15 matching lines...) Expand all Loading... | |
1239 | 1351 |
1240 socket->GetLocalAddress(&local_address_); | 1352 socket->GetLocalAddress(&local_address_); |
1241 if (check_persisted_supports_quic_ && http_server_properties_) { | 1353 if (check_persisted_supports_quic_ && http_server_properties_) { |
1242 check_persisted_supports_quic_ = false; | 1354 check_persisted_supports_quic_ = false; |
1243 IPAddressNumber last_address; | 1355 IPAddressNumber last_address; |
1244 if (http_server_properties_->GetSupportsQuic(&last_address) && | 1356 if (http_server_properties_->GetSupportsQuic(&last_address) && |
1245 last_address == local_address_.address()) { | 1357 last_address == local_address_.address()) { |
1246 require_confirmation_ = false; | 1358 require_confirmation_ = false; |
1247 } | 1359 } |
1248 } | 1360 } |
1361 return OK; | |
1362 } | |
1363 | |
1364 int QuicStreamFactory::CreateSession(const QuicServerId& server_id, | |
1365 int cert_verify_flags, | |
1366 scoped_ptr<QuicServerInfo> server_info, | |
1367 const AddressList& address_list, | |
1368 base::TimeTicks dns_resolution_end_time, | |
1369 const BoundNetLog& net_log, | |
1370 QuicChromiumClientSession** session) { | |
1371 scoped_ptr<DatagramClientSocket> socket; | |
1372 int rv = CreateAndConfigureDatagramSocket(&socket, | |
1373 server_id, | |
1374 *address_list.begin(), | |
1375 net_log, | |
1376 kDefaultNetworkHandle); | |
1377 if (rv != OK) { | |
1378 return rv; | |
1379 } | |
1249 | 1380 |
1250 DefaultPacketWriterFactory packet_writer_factory(socket.get()); | 1381 DefaultPacketWriterFactory packet_writer_factory(socket.get()); |
1251 | |
1252 if (!helper_.get()) { | 1382 if (!helper_.get()) { |
1253 helper_.reset( | 1383 helper_.reset( |
1254 new QuicConnectionHelper(base::ThreadTaskRunnerHandle::Get().get(), | 1384 new QuicConnectionHelper(base::ThreadTaskRunnerHandle::Get().get(), |
1255 clock_.get(), random_generator_)); | 1385 clock_.get(), random_generator_)); |
1256 } | 1386 } |
1257 | 1387 |
1388 QuicConnectionId connection_id = random_generator_->RandUint64(); | |
1258 QuicConnection* connection = new QuicConnection( | 1389 QuicConnection* connection = new QuicConnection( |
1259 connection_id, addr, helper_.get(), packet_writer_factory, | 1390 connection_id, addr, helper_.get(), packet_writer_factory, |
1260 true /* owns_writer */, Perspective::IS_CLIENT, server_id.is_https(), | 1391 true /* owns_writer */, Perspective::IS_CLIENT, server_id.is_https(), |
1261 supported_versions_); | 1392 supported_versions_); |
1262 connection->SetMaxPacketLength(max_packet_length_); | 1393 connection->SetMaxPacketLength(max_packet_length_); |
1263 | 1394 |
1264 InitializeCachedStateInCryptoConfig(server_id, server_info); | 1395 InitializeCachedStateInCryptoConfig(server_id, server_info); |
1265 | 1396 |
1266 QuicConfig config = config_; | 1397 QuicConfig config = config_; |
1267 config.SetSocketReceiveBufferToSend(socket_receive_buffer_size_); | 1398 config.SetSocketReceiveBufferToSend(socket_receive_buffer_size_); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1446 // Since the session was active, there's no longer an | 1577 // Since the session was active, there's no longer an |
1447 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 1578 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
1448 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 1579 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
1449 // it as recently broken, which means that 0-RTT will be disabled but we'll | 1580 // it as recently broken, which means that 0-RTT will be disabled but we'll |
1450 // still race. | 1581 // still race. |
1451 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 1582 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
1452 alternative_service); | 1583 alternative_service); |
1453 } | 1584 } |
1454 | 1585 |
1455 } // namespace net | 1586 } // namespace net |
OLD | NEW |