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/chromium/quic_chromium_client_session.h" | 5 #include "net/quic/chromium/quic_chromium_client_session.h" |
6 | 6 |
7 #include <openssl/ssl.h> | 7 #include <openssl/ssl.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
50 // connection migration. A new Reader is created every time this endpoint's | 50 // connection migration. A new Reader is created every time this endpoint's |
51 // IP address changes. | 51 // IP address changes. |
52 const size_t kMaxReadersPerQuicSession = 5; | 52 const size_t kMaxReadersPerQuicSession = 5; |
53 | 53 |
54 // Size of the MRU cache of Token Binding signatures. Since the material being | 54 // Size of the MRU cache of Token Binding signatures. Since the material being |
55 // signed is constant and there aren't many keys being used to sign, a fairly | 55 // signed is constant and there aren't many keys being used to sign, a fairly |
56 // small number was chosen, somewhat arbitrarily, and to match | 56 // small number was chosen, somewhat arbitrarily, and to match |
57 // SSLClientSocketImpl. | 57 // SSLClientSocketImpl. |
58 const size_t kTokenBindingSignatureMapSize = 10; | 58 const size_t kTokenBindingSignatureMapSize = 10; |
59 | 59 |
60 // Time to wait (in seconds) when no networks are available and | |
61 // migrating sessions need to wait for a new network to connect. | |
62 const size_t kWaitTimeForNewNetworkSecs = 10; | |
63 | |
60 // Histograms for tracking down the crashes from http://crbug.com/354669 | 64 // Histograms for tracking down the crashes from http://crbug.com/354669 |
61 // Note: these values must be kept in sync with the corresponding values in: | 65 // Note: these values must be kept in sync with the corresponding values in: |
62 // tools/metrics/histograms/histograms.xml | 66 // tools/metrics/histograms/histograms.xml |
63 enum Location { | 67 enum Location { |
64 DESTRUCTOR = 0, | 68 DESTRUCTOR = 0, |
65 ADD_OBSERVER = 1, | 69 ADD_OBSERVER = 1, |
66 TRY_CREATE_STREAM = 2, | 70 TRY_CREATE_STREAM = 2, |
67 CREATE_OUTGOING_RELIABLE_STREAM = 3, | 71 CREATE_OUTGOING_RELIABLE_STREAM = 3, |
68 NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER = 4, | 72 NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER = 4, |
69 NOTIFY_FACTORY_OF_SESSION_CLOSED = 5, | 73 NOTIFY_FACTORY_OF_SESSION_CLOSED = 5, |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
235 connection_description, | 239 connection_description, |
236 std::move(socket_performance_watcher), | 240 std::move(socket_performance_watcher), |
237 net_log_)), | 241 net_log_)), |
238 going_away_(false), | 242 going_away_(false), |
239 port_migration_detected_(false), | 243 port_migration_detected_(false), |
240 disabled_reason_(QUIC_DISABLED_NOT), | 244 disabled_reason_(QUIC_DISABLED_NOT), |
241 token_binding_signatures_(kTokenBindingSignatureMapSize), | 245 token_binding_signatures_(kTokenBindingSignatureMapSize), |
242 streams_pushed_count_(0), | 246 streams_pushed_count_(0), |
243 streams_pushed_and_claimed_count_(0), | 247 streams_pushed_and_claimed_count_(0), |
244 migration_pending_(false), | 248 migration_pending_(false), |
249 migration_alarm_pending_(false), | |
245 weak_factory_(this) { | 250 weak_factory_(this) { |
246 sockets_.push_back(std::move(socket)); | 251 sockets_.push_back(std::move(socket)); |
247 packet_readers_.push_back(base::MakeUnique<QuicChromiumPacketReader>( | 252 packet_readers_.push_back(base::MakeUnique<QuicChromiumPacketReader>( |
248 sockets_.back().get(), clock, this, yield_after_packets, | 253 sockets_.back().get(), clock, this, yield_after_packets, |
249 yield_after_duration, net_log_)); | 254 yield_after_duration, net_log_)); |
250 crypto_stream_.reset( | 255 crypto_stream_.reset( |
251 crypto_client_stream_factory->CreateQuicCryptoClientStream( | 256 crypto_client_stream_factory->CreateQuicCryptoClientStream( |
252 server_id, this, base::MakeUnique<ProofVerifyContextChromium>( | 257 server_id, this, base::MakeUnique<ProofVerifyContextChromium>( |
253 cert_verify_flags, net_log_), | 258 cert_verify_flags, net_log_), |
254 crypto_config)); | 259 crypto_config)); |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
992 // Cause the packet writer to return ERR_IO_PENDING and block so | 997 // Cause the packet writer to return ERR_IO_PENDING and block so |
993 // that the actual migration happens from the message loop instead | 998 // that the actual migration happens from the message loop instead |
994 // of under the call stack of QuicConnection::WritePacket. | 999 // of under the call stack of QuicConnection::WritePacket. |
995 return ERR_IO_PENDING; | 1000 return ERR_IO_PENDING; |
996 } | 1001 } |
997 | 1002 |
998 void QuicChromiumClientSession::MigrateSessionOnWriteError() { | 1003 void QuicChromiumClientSession::MigrateSessionOnWriteError() { |
999 // If migration_pending_ is false, an earlier task completed migration. | 1004 // If migration_pending_ is false, an earlier task completed migration. |
1000 if (!migration_pending_) | 1005 if (!migration_pending_) |
1001 return; | 1006 return; |
1002 | 1007 |
Ryan Hamilton
2016/09/13 02:57:31
What happened to all the vertical white space? I f
Jana
2016/09/13 03:12:14
I wasn't sure if it was too much white space, so I
| |
1003 if (stream_factory_ != nullptr && | 1008 MigrationResult result = MigrationResult::FAILURE; |
1004 stream_factory_->MaybeMigrateSingleSession(this, WRITE_ERROR) == | 1009 if (stream_factory_ != nullptr) { |
1005 MigrationResult::SUCCESS) { | 1010 result = stream_factory_->MaybeMigrateSingleSession(this, WRITE_ERROR); |
1011 } | |
1012 | |
1013 if (result == MigrationResult::SUCCESS) | |
1014 return; | |
1015 | |
1016 if (result == MigrationResult::NO_NEW_NETWORK) { | |
1017 OnNoNewNetwork(); | |
1006 return; | 1018 return; |
1007 } | 1019 } |
1008 | 1020 |
1009 // Close the connection if migration failed. Do not cause a | 1021 // Close the connection if migration failed. Do not cause a |
1010 // connection close packet to be sent since socket may be borked. | 1022 // connection close packet to be sent since socket may be borked. |
1011 connection()->CloseConnection(QUIC_PACKET_WRITE_ERROR, | 1023 connection()->CloseConnection(QUIC_PACKET_WRITE_ERROR, |
1012 "Write and subsequent migration failed", | 1024 "Write and subsequent migration failed", |
1013 ConnectionCloseBehavior::SILENT_CLOSE); | 1025 ConnectionCloseBehavior::SILENT_CLOSE); |
1014 } | 1026 } |
1015 | 1027 |
1028 void QuicChromiumClientSession::OnNoNewNetwork() { | |
1029 if (migration_alarm_pending_) | |
1030 return; | |
1031 migration_alarm_pending_ = true; | |
1032 // When called from a network notification, migration_pending_ must | |
1033 // be set to true here. | |
Ryan Hamilton
2016/09/13 00:33:18
I don't understand this comment. Perhaps you can e
Jana
2016/09/13 01:12:19
Comment changed PTAL.
| |
1034 migration_pending_ = true; | |
1035 | |
1036 // Block the packet writer to avoid any writes while migration is in progress. | |
1037 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) | |
1038 ->set_write_blocked(true); | |
1039 | |
1040 // Post a task to maybe close the session if the alarm fires. | |
1041 task_runner_->PostDelayedTask( | |
1042 FROM_HERE, base::Bind(&QuicChromiumClientSession::OnMigrationTimeout, | |
1043 weak_factory_.GetWeakPtr()), | |
1044 base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs)); | |
1045 } | |
1046 | |
1016 void QuicChromiumClientSession::WriteToNewSocket() { | 1047 void QuicChromiumClientSession::WriteToNewSocket() { |
1017 // Prevent any pending migration from executing. | 1048 // Prevent any pending migration from executing. |
1018 migration_pending_ = false; | 1049 migration_pending_ = false; |
1019 | 1050 |
1020 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) | 1051 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) |
1021 ->set_write_blocked(false); | 1052 ->set_write_blocked(false); |
1022 DCHECK(!connection()->writer()->IsWriteBlocked()); | 1053 DCHECK(!connection()->writer()->IsWriteBlocked()); |
1023 | 1054 |
1024 if (packet_ == nullptr) { | 1055 if (packet_ == nullptr) { |
1025 // Unblock the connection before sending a PING packet, since it | 1056 // Unblock the connection before sending a PING packet, since it |
(...skipping 17 matching lines...) Expand all Loading... | |
1043 ->WritePacketToSocket(packet); | 1074 ->WritePacketToSocket(packet); |
1044 | 1075 |
1045 if (result.error_code == ERR_IO_PENDING) | 1076 if (result.error_code == ERR_IO_PENDING) |
1046 return; | 1077 return; |
1047 // All write errors should be mapped into ERR_IO_PENDING by | 1078 // All write errors should be mapped into ERR_IO_PENDING by |
1048 // HandleWriteError. | 1079 // HandleWriteError. |
1049 DCHECK_LT(0, result.error_code); | 1080 DCHECK_LT(0, result.error_code); |
1050 connection()->OnCanWrite(); | 1081 connection()->OnCanWrite(); |
1051 } | 1082 } |
1052 | 1083 |
1084 void QuicChromiumClientSession::OnMigrationTimeout() { | |
1085 DLOG(INFO) << "In OnMigrationTimeout: migration_pending_: " << migration_pendi ng_; | |
Ryan Hamilton
2016/09/13 00:33:18
nit: remove this?
Jana
2016/09/13 01:12:19
Done.
| |
1086 if (!migration_pending_) | |
Ryan Hamilton
2016/09/13 00:33:18
As discussed, if two migrations start before the f
Jana
2016/09/13 01:12:18
Changed to using sockets_.size().
| |
1087 return; | |
1088 migration_alarm_pending_ = false; | |
1089 migration_pending_ = false; | |
Ryan Hamilton
2016/09/13 00:33:18
Since the connection is about to be deleted, I sus
Jana
2016/09/13 01:12:18
Yup, removed.
| |
1090 /* | |
1091 UMA_HISTOGRAM_ENUMERATION( | |
1092 "Net.QuicSession.ConnectionMigration", | |
1093 static_cast<int>(MigrationStatus::NO_ALTERNATE_NETWORK), | |
1094 static_cast<int>(MigrationStatus::MAX)); | |
1095 */ | |
Ryan Hamilton
2016/09/13 00:33:18
What's up with this?
Jana
2016/09/13 01:12:18
Fixed.
| |
1096 CloseSessionOnError(ERR_NETWORK_CHANGED, | |
1097 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK); | |
1098 } | |
1099 | |
1100 void QuicChromiumClientSession::OnNetworkConnected( | |
1101 NetworkChangeNotifier::NetworkHandle network, | |
1102 const BoundNetLog& bound_net_log) { | |
1103 // Cancel migration alarm if one is pending. | |
1104 migration_alarm_pending_ = false; | |
1105 // If migration_pending_ is false, there was no migration pending or | |
1106 // an earlier task completed migration. | |
1107 if (!migration_pending_) | |
1108 return; | |
1109 // TODO(jri): Ensure that OnSessionGoingAway is called consistently, | |
1110 // and that it's always called at the same time in the whole | |
1111 // migration process. Allows tests to be more uniform. | |
1112 stream_factory_->OnSessionGoingAway(this); | |
1113 stream_factory_->MigrateSessionToNewNetwork( | |
1114 this, network, /*close_session_on_error=*/true, net_log_); | |
1115 } | |
1116 | |
1053 void QuicChromiumClientSession::OnWriteError(int error_code) { | 1117 void QuicChromiumClientSession::OnWriteError(int error_code) { |
1054 DCHECK_NE(ERR_IO_PENDING, error_code); | 1118 DCHECK_NE(ERR_IO_PENDING, error_code); |
1055 DCHECK_GT(0, error_code); | 1119 DCHECK_GT(0, error_code); |
1056 connection()->OnWriteError(error_code); | 1120 connection()->OnWriteError(error_code); |
1057 } | 1121 } |
1058 | 1122 |
1059 void QuicChromiumClientSession::OnWriteUnblocked() { | 1123 void QuicChromiumClientSession::OnWriteUnblocked() { |
1060 connection()->OnCanWrite(); | 1124 connection()->OnCanWrite(); |
1061 } | 1125 } |
1062 | 1126 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1331 } | 1395 } |
1332 | 1396 |
1333 void QuicChromiumClientSession::DeletePromised( | 1397 void QuicChromiumClientSession::DeletePromised( |
1334 QuicClientPromisedInfo* promised) { | 1398 QuicClientPromisedInfo* promised) { |
1335 if (IsOpenStream(promised->id())) | 1399 if (IsOpenStream(promised->id())) |
1336 streams_pushed_and_claimed_count_++; | 1400 streams_pushed_and_claimed_count_++; |
1337 QuicClientSessionBase::DeletePromised(promised); | 1401 QuicClientSessionBase::DeletePromised(promised); |
1338 } | 1402 } |
1339 | 1403 |
1340 } // namespace net | 1404 } // namespace net |
OLD | NEW |