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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 logger_(new QuicConnectionLogger(this, | 230 logger_(new QuicConnectionLogger(this, |
231 connection_description, | 231 connection_description, |
232 std::move(socket_performance_watcher), | 232 std::move(socket_performance_watcher), |
233 net_log_)), | 233 net_log_)), |
234 going_away_(false), | 234 going_away_(false), |
235 port_migration_detected_(false), | 235 port_migration_detected_(false), |
236 disabled_reason_(QUIC_DISABLED_NOT), | 236 disabled_reason_(QUIC_DISABLED_NOT), |
237 token_binding_signatures_(kTokenBindingSignatureMapSize), | 237 token_binding_signatures_(kTokenBindingSignatureMapSize), |
238 streams_pushed_count_(0), | 238 streams_pushed_count_(0), |
239 streams_pushed_and_claimed_count_(0), | 239 streams_pushed_and_claimed_count_(0), |
240 error_code_from_rewrite_(OK), | 240 migration_pending_(false), |
241 use_error_code_from_rewrite_(false), | 241 write_pending_(false), |
242 weak_factory_(this) { | 242 weak_factory_(this) { |
243 sockets_.push_back(std::move(socket)); | 243 sockets_.push_back(std::move(socket)); |
244 packet_readers_.push_back(base::WrapUnique(new QuicChromiumPacketReader( | 244 packet_readers_.push_back(base::WrapUnique(new QuicChromiumPacketReader( |
245 sockets_.back().get(), clock, this, yield_after_packets, | 245 sockets_.back().get(), clock, this, yield_after_packets, |
246 yield_after_duration, net_log_))); | 246 yield_after_duration, net_log_))); |
247 crypto_stream_.reset( | 247 crypto_stream_.reset( |
248 crypto_client_stream_factory->CreateQuicCryptoClientStream( | 248 crypto_client_stream_factory->CreateQuicCryptoClientStream( |
249 server_id, this, base::WrapUnique(new ProofVerifyContextChromium( | 249 server_id, this, base::WrapUnique(new ProofVerifyContextChromium( |
250 cert_verify_flags, net_log_)), | 250 cert_verify_flags, net_log_)), |
251 crypto_config)); | 251 crypto_config)); |
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
945 void QuicChromiumClientSession::OnSuccessfulVersionNegotiation( | 945 void QuicChromiumClientSession::OnSuccessfulVersionNegotiation( |
946 const QuicVersion& version) { | 946 const QuicVersion& version) { |
947 logger_->OnSuccessfulVersionNegotiation(version); | 947 logger_->OnSuccessfulVersionNegotiation(version); |
948 QuicSpdySession::OnSuccessfulVersionNegotiation(version); | 948 QuicSpdySession::OnSuccessfulVersionNegotiation(version); |
949 } | 949 } |
950 | 950 |
951 int QuicChromiumClientSession::HandleWriteError( | 951 int QuicChromiumClientSession::HandleWriteError( |
952 int error_code, | 952 int error_code, |
953 scoped_refptr<StringIOBuffer> packet) { | 953 scoped_refptr<StringIOBuffer> packet) { |
954 DCHECK(packet != nullptr); | 954 DCHECK(packet != nullptr); |
955 use_error_code_from_rewrite_ = false; | 955 DCHECK_NE(ERR_IO_PENDING, error_code); |
956 if (stream_factory_) { | 956 DCHECK_GT(0, error_code); |
957 stream_factory_->MaybeMigrateSingleSession(this, WRITE_ERROR, packet); | 957 DCHECK(!migration_pending_); |
958 DCHECK(packet_ == nullptr); | |
959 | |
960 // Post a task to migrate the session onto a new network. | |
961 task_runner_->PostTask( | |
962 FROM_HERE, | |
963 base::Bind(&QuicChromiumClientSession::MigrateSessionOnWriteError, | |
964 weak_factory_.GetWeakPtr())); | |
965 | |
966 // Store packet in the session since the actual migration and packet rewrite | |
967 // can happen via this posted task or via an async network notification. | |
968 packet_ = packet; | |
969 migration_pending_ = true; | |
Ryan Hamilton
2016/09/12 00:52:18
This is the only place migration_pending_ is set t
Jana
2016/09/12 21:08:02
This is used (later in the pause CL) by the NCN co
| |
970 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) | |
971 ->set_write_blocked(true); | |
Ryan Hamilton
2016/09/12 00:52:18
This is not needed is it? By returning ERR_IO_PEND
Jana
2016/09/12 21:08:02
Oh of course -- I am not sure why I added this her
| |
972 | |
973 // Cause the packet writer to return ERR_IO_PENDING and block so | |
974 // that the actual migration happens from the message loop instead | |
975 // of under the call stack of QuicConnection::WritePacket. | |
976 return ERR_IO_PENDING; | |
977 } | |
978 | |
979 void QuicChromiumClientSession::MigrateSessionOnWriteError() { | |
980 // If migration_pending_ is false, an earlier task completed migration. | |
981 if (!migration_pending_) | |
982 return; | |
983 | |
984 if (stream_factory_ != nullptr && | |
985 stream_factory_->MaybeMigrateSingleSession(this, WRITE_ERROR) == | |
986 MigrationResult::SUCCESS) | |
987 return; | |
Ryan Hamilton
2016/09/12 00:52:18
nit: {}s needed.
Jana
2016/09/12 21:08:02
Done.
| |
988 | |
989 // Close the connection if migration failed. Do not cause a | |
990 // connection close packet to be sent since socket may be borked. | |
991 connection()->CloseConnection(QUIC_PACKET_WRITE_ERROR, | |
992 "Write and subsequent migration failed", | |
993 ConnectionCloseBehavior::SILENT_CLOSE); | |
994 } | |
995 | |
996 void QuicChromiumClientSession::WriteToNewSocket() { | |
997 // If write_pending_ is false, an earlier task wrote to the new socket. | |
998 if (!write_pending_) | |
999 return; | |
Ryan Hamilton
2016/09/12 01:32:57
You can take this or leave it... If we removed thi
Jana
2016/09/12 21:08:02
I did have the code doing that earlier, but enforc
| |
1000 // Prevent any pending migration or write tasks from executing. | |
1001 write_pending_ = false; | |
1002 migration_pending_ = false; | |
1003 | |
1004 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) | |
1005 ->set_write_blocked(false); | |
1006 DCHECK(!connection()->writer()->IsWriteBlocked()); | |
1007 | |
1008 if (packet_ == nullptr) { | |
1009 connection()->SendPing(); | |
1010 // The connection may have been blocked before the migration | |
1011 // started. Unblock the connection if sending the PING packet did | |
1012 // not leave the writer blocked. | |
Ryan Hamilton
2016/09/12 00:52:18
I think the best thing to do is to call OnCanWrite
Jana
2016/09/12 21:08:02
Hm. Yeah, this does make reasoning simpler. Done.
| |
1013 if (!connection()->writer()->IsWriteBlocked()) | |
1014 connection()->OnCanWrite(); | |
1015 return; | |
958 } | 1016 } |
959 return use_error_code_from_rewrite_ ? error_code_from_rewrite_ : error_code; | 1017 |
1018 // Set packet_ to null first. We cannot set packet_ to null after | |
1019 // the following write since the write may result in packet_ being | |
1020 // reused via a write error. | |
Ryan Hamilton
2016/09/12 00:52:18
Avoid first person in comments:
// Set packet t
Jana
2016/09/12 21:08:02
Done.
| |
1021 scoped_refptr<StringIOBuffer> packet = packet_; | |
1022 packet_ = nullptr; | |
1023 | |
1024 // The connection is waiting for the original write to complete | |
1025 // asynchronously. The new writer will notify the connection if the | |
1026 // write below completes asynchronously, but a synchronous competion | |
1027 // must be propagated back to the connection here. | |
1028 WriteResult result = | |
1029 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) | |
1030 ->WritePacketToSocket(packet); | |
1031 | |
1032 if (result.error_code == ERR_IO_PENDING) | |
1033 return; | |
1034 // All write errors should be mapped into ERR_IO_PENDING by | |
1035 // HandleWriteError. | |
1036 DCHECK(result.error_code >= 0); | |
Ryan Hamilton
2016/09/12 00:52:18
nit: DCHECK_LT(0, result.error_code);
Jana
2016/09/12 21:08:02
Done.
| |
1037 connection()->OnCanWrite(); | |
960 } | 1038 } |
961 | 1039 |
962 void QuicChromiumClientSession::OnWriteError(int error_code) { | 1040 void QuicChromiumClientSession::OnWriteError(int error_code) { |
963 DCHECK_NE(ERR_IO_PENDING, error_code); | 1041 DCHECK_NE(ERR_IO_PENDING, error_code); |
964 DCHECK_GT(0, error_code); | 1042 DCHECK_GT(0, error_code); |
965 connection()->OnWriteError(error_code); | 1043 connection()->OnWriteError(error_code); |
966 } | 1044 } |
967 | 1045 |
968 void QuicChromiumClientSession::OnWriteUnblocked() { | 1046 void QuicChromiumClientSession::OnWriteUnblocked() { |
969 connection()->OnCanWrite(); | 1047 connection()->OnCanWrite(); |
970 } | 1048 } |
971 | 1049 |
972 void QuicChromiumClientSession::OnPathDegrading() { | 1050 void QuicChromiumClientSession::OnPathDegrading() { |
973 if (stream_factory_) { | 1051 if (stream_factory_) { |
974 stream_factory_->MaybeMigrateSingleSession(this, EARLY_MIGRATION, nullptr); | 1052 stream_factory_->MaybeMigrateSingleSession(this, EARLY_MIGRATION); |
975 } | 1053 } |
976 } | 1054 } |
977 | 1055 |
978 bool QuicChromiumClientSession::HasOpenDynamicStreams() const { | 1056 bool QuicChromiumClientSession::HasOpenDynamicStreams() const { |
979 return QuicSession::HasOpenDynamicStreams() || | 1057 return QuicSession::HasOpenDynamicStreams() || |
980 GetNumDrainingOutgoingStreams() > 0; | 1058 GetNumDrainingOutgoingStreams() > 0; |
981 } | 1059 } |
982 | 1060 |
983 void QuicChromiumClientSession::OnProofValid( | 1061 void QuicChromiumClientSession::OnProofValid( |
984 const QuicCryptoClientConfig::CachedState& cached) { | 1062 const QuicCryptoClientConfig::CachedState& cached) { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1171 going_away_ = true; | 1249 going_away_ = true; |
1172 DCHECK_EQ(0u, GetNumActiveStreams()); | 1250 DCHECK_EQ(0u, GetNumActiveStreams()); |
1173 // Will delete |this|. | 1251 // Will delete |this|. |
1174 if (stream_factory_) | 1252 if (stream_factory_) |
1175 stream_factory_->OnSessionClosed(this); | 1253 stream_factory_->OnSessionClosed(this); |
1176 } | 1254 } |
1177 | 1255 |
1178 bool QuicChromiumClientSession::MigrateToSocket( | 1256 bool QuicChromiumClientSession::MigrateToSocket( |
1179 std::unique_ptr<DatagramClientSocket> socket, | 1257 std::unique_ptr<DatagramClientSocket> socket, |
1180 std::unique_ptr<QuicChromiumPacketReader> reader, | 1258 std::unique_ptr<QuicChromiumPacketReader> reader, |
1181 std::unique_ptr<QuicChromiumPacketWriter> writer, | 1259 std::unique_ptr<QuicChromiumPacketWriter> writer) { |
1182 scoped_refptr<StringIOBuffer> packet) { | |
1183 DCHECK_EQ(sockets_.size(), packet_readers_.size()); | 1260 DCHECK_EQ(sockets_.size(), packet_readers_.size()); |
1184 if (sockets_.size() >= kMaxReadersPerQuicSession) { | 1261 if (sockets_.size() >= kMaxReadersPerQuicSession) |
1185 return false; | 1262 return false; |
1186 } | 1263 |
1187 // TODO(jri): Make SetQuicPacketWriter take a scoped_ptr. | 1264 // TODO(jri): Make SetQuicPacketWriter take a scoped_ptr. |
1188 packet_readers_.push_back(std::move(reader)); | 1265 packet_readers_.push_back(std::move(reader)); |
1189 sockets_.push_back(std::move(socket)); | 1266 sockets_.push_back(std::move(socket)); |
1190 StartReading(); | 1267 StartReading(); |
1191 QuicChromiumPacketWriter* raw_writer = writer.get(); | |
1192 connection()->SetQuicPacketWriter(writer.release(), /*owns_writer=*/true); | 1268 connection()->SetQuicPacketWriter(writer.release(), /*owns_writer=*/true); |
1193 if (packet == nullptr) { | 1269 |
1194 connection()->SendPing(); | 1270 // Post task to write the pending packet or a PING packet to the new |
1195 return true; | 1271 // socket. Also block the writer to prevent is being used until |
Ryan Hamilton
2016/09/12 00:52:18
Can you add some language here which explains that
Jana
2016/09/12 21:08:02
Done.
| |
1196 } | 1272 // WriteToNewSocket completes. |
Ryan Hamilton
2016/09/12 00:52:18
nit: move this sentence down to the call to block
Jana
2016/09/12 21:08:02
Done.
| |
1197 // Packet rewrite after migration on socket write error. | 1273 task_runner_->PostTask( |
1198 error_code_from_rewrite_ = raw_writer->WritePacketToSocket(packet.get()); | 1274 FROM_HERE, base::Bind(&QuicChromiumClientSession::WriteToNewSocket, |
1199 use_error_code_from_rewrite_ = true; | 1275 weak_factory_.GetWeakPtr())); |
1276 | |
1277 // Block the writer until the task posted is executed. | |
1278 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) | |
1279 ->set_write_blocked(true); | |
1280 | |
1281 // Migration completed and write task posted. | |
1282 migration_pending_ = false; | |
1283 write_pending_ = true; | |
1200 return true; | 1284 return true; |
1201 } | 1285 } |
1202 | 1286 |
1203 void QuicChromiumClientSession::PopulateNetErrorDetails( | 1287 void QuicChromiumClientSession::PopulateNetErrorDetails( |
1204 NetErrorDetails* details) { | 1288 NetErrorDetails* details) { |
1205 details->quic_port_migration_detected = port_migration_detected_; | 1289 details->quic_port_migration_detected = port_migration_detected_; |
1206 } | 1290 } |
1207 | 1291 |
1208 const DatagramClientSocket* QuicChromiumClientSession::GetDefaultSocket() | 1292 const DatagramClientSocket* QuicChromiumClientSession::GetDefaultSocket() |
1209 const { | 1293 const { |
(...skipping 27 matching lines...) Expand all Loading... | |
1237 } | 1321 } |
1238 | 1322 |
1239 void QuicChromiumClientSession::DeletePromised( | 1323 void QuicChromiumClientSession::DeletePromised( |
1240 QuicClientPromisedInfo* promised) { | 1324 QuicClientPromisedInfo* promised) { |
1241 if (IsOpenStream(promised->id())) | 1325 if (IsOpenStream(promised->id())) |
1242 streams_pushed_and_claimed_count_++; | 1326 streams_pushed_and_claimed_count_++; |
1243 QuicClientSessionBase::DeletePromised(promised); | 1327 QuicClientSessionBase::DeletePromised(promised); |
1244 } | 1328 } |
1245 | 1329 |
1246 } // namespace net | 1330 } // namespace net |
OLD | NEW |