Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: net/quic/chromium/quic_chromium_client_session.cc

Issue 2329853002: Introduces ability for session to wait on a migration trigger for a new (Closed)
Patch Set: network notifications handled Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 // connection migration. A new Reader is created every time this endpoint's 46 // connection migration. A new Reader is created every time this endpoint's
47 // IP address changes. 47 // IP address changes.
48 const size_t kMaxReadersPerQuicSession = 5; 48 const size_t kMaxReadersPerQuicSession = 5;
49 49
50 // Size of the MRU cache of Token Binding signatures. Since the material being 50 // Size of the MRU cache of Token Binding signatures. Since the material being
51 // signed is constant and there aren't many keys being used to sign, a fairly 51 // signed is constant and there aren't many keys being used to sign, a fairly
52 // small number was chosen, somewhat arbitrarily, and to match 52 // small number was chosen, somewhat arbitrarily, and to match
53 // SSLClientSocketImpl. 53 // SSLClientSocketImpl.
54 const size_t kTokenBindingSignatureMapSize = 10; 54 const size_t kTokenBindingSignatureMapSize = 10;
55 55
56 // Time to wait (in seconds) when no networks are available and
57 // migrating sessions need to wait for a new network to connect.
58 const size_t kWaitTimeForNewNetworkSecs = 10;
59
56 // Histograms for tracking down the crashes from http://crbug.com/354669 60 // Histograms for tracking down the crashes from http://crbug.com/354669
57 // Note: these values must be kept in sync with the corresponding values in: 61 // Note: these values must be kept in sync with the corresponding values in:
58 // tools/metrics/histograms/histograms.xml 62 // tools/metrics/histograms/histograms.xml
59 enum Location { 63 enum Location {
60 DESTRUCTOR = 0, 64 DESTRUCTOR = 0,
61 ADD_OBSERVER = 1, 65 ADD_OBSERVER = 1,
62 TRY_CREATE_STREAM = 2, 66 TRY_CREATE_STREAM = 2,
63 CREATE_OUTGOING_RELIABLE_STREAM = 3, 67 CREATE_OUTGOING_RELIABLE_STREAM = 3,
64 NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER = 4, 68 NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER = 4,
65 NOTIFY_FACTORY_OF_SESSION_CLOSED = 5, 69 NOTIFY_FACTORY_OF_SESSION_CLOSED = 5,
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 std::move(socket_performance_watcher), 236 std::move(socket_performance_watcher),
233 net_log_)), 237 net_log_)),
234 going_away_(false), 238 going_away_(false),
235 port_migration_detected_(false), 239 port_migration_detected_(false),
236 disabled_reason_(QUIC_DISABLED_NOT), 240 disabled_reason_(QUIC_DISABLED_NOT),
237 token_binding_signatures_(kTokenBindingSignatureMapSize), 241 token_binding_signatures_(kTokenBindingSignatureMapSize),
238 streams_pushed_count_(0), 242 streams_pushed_count_(0),
239 streams_pushed_and_claimed_count_(0), 243 streams_pushed_and_claimed_count_(0),
240 migration_pending_(false), 244 migration_pending_(false),
241 write_pending_(false), 245 write_pending_(false),
246 migration_alarm_pending_(false),
242 weak_factory_(this) { 247 weak_factory_(this) {
243 sockets_.push_back(std::move(socket)); 248 sockets_.push_back(std::move(socket));
244 packet_readers_.push_back(base::WrapUnique(new QuicChromiumPacketReader( 249 packet_readers_.push_back(base::WrapUnique(new QuicChromiumPacketReader(
245 sockets_.back().get(), clock, this, yield_after_packets, 250 sockets_.back().get(), clock, this, yield_after_packets,
246 yield_after_duration, net_log_))); 251 yield_after_duration, net_log_)));
247 crypto_stream_.reset( 252 crypto_stream_.reset(
248 crypto_client_stream_factory->CreateQuicCryptoClientStream( 253 crypto_client_stream_factory->CreateQuicCryptoClientStream(
249 server_id, this, base::WrapUnique(new ProofVerifyContextChromium( 254 server_id, this, base::WrapUnique(new ProofVerifyContextChromium(
250 cert_verify_flags, net_log_)), 255 cert_verify_flags, net_log_)),
251 crypto_config)); 256 crypto_config));
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 955
951 int QuicChromiumClientSession::HandleWriteError( 956 int QuicChromiumClientSession::HandleWriteError(
952 int error_code, 957 int error_code,
953 scoped_refptr<StringIOBuffer> packet) { 958 scoped_refptr<StringIOBuffer> packet) {
954 DCHECK(packet != nullptr); 959 DCHECK(packet != nullptr);
955 DCHECK_NE(ERR_IO_PENDING, error_code); 960 DCHECK_NE(ERR_IO_PENDING, error_code);
956 DCHECK_GT(0, error_code); 961 DCHECK_GT(0, error_code);
957 DCHECK(!migration_pending_); 962 DCHECK(!migration_pending_);
958 DCHECK(packet_ == nullptr); 963 DCHECK(packet_ == nullptr);
959 964
965 DLOG(INFO) << "Write error encountered.";
960 // Post a task to migrate the session onto a new network. 966 // Post a task to migrate the session onto a new network.
961 task_runner_->PostTask( 967 task_runner_->PostTask(
962 FROM_HERE, 968 FROM_HERE,
963 base::Bind(&QuicChromiumClientSession::MigrateSessionOnWriteError, 969 base::Bind(&QuicChromiumClientSession::MigrateSessionOnWriteError,
964 weak_factory_.GetWeakPtr())); 970 weak_factory_.GetWeakPtr()));
965 971
966 // Store packet in the session since the actual migration and packet rewrite 972 // 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. 973 // can happen via this posted task or via an async network notification.
968 packet_ = packet; 974 packet_ = packet;
969 migration_pending_ = true; 975 migration_pending_ = true;
970 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) 976 static_cast<QuicChromiumPacketWriter*>(connection()->writer())
971 ->set_write_blocked(true); 977 ->set_write_blocked(true);
972 978
973 // Cause the packet writer to return ERR_IO_PENDING and block so 979 // Cause the packet writer to return ERR_IO_PENDING and block so
974 // that the actual migration happens from the message loop instead 980 // that the actual migration happens from the message loop instead
975 // of under the call stack of QuicConnection::WritePacket. 981 // of under the call stack of QuicConnection::WritePacket.
976 return ERR_IO_PENDING; 982 return ERR_IO_PENDING;
977 } 983 }
978 984
979 void QuicChromiumClientSession::MigrateSessionOnWriteError() { 985 void QuicChromiumClientSession::MigrateSessionOnWriteError() {
980 // If migration_pending_ is false, an earlier task completed migration. 986 // If migration_pending_ is false, an earlier task completed migration.
981 if (!migration_pending_) 987 if (!migration_pending_)
982 return; 988 return;
983 989
984 if (stream_factory_ != nullptr && 990 MigrationResult result = MigrationResult::FAILURE;
985 stream_factory_->MaybeMigrateSingleSession(this, WRITE_ERROR) == 991 if (stream_factory_ != nullptr) {
986 MigrationResult::SUCCESS) 992 result = stream_factory_->MaybeMigrateSingleSession(this, WRITE_ERROR);
993 }
994
995 if (result == MigrationResult::SUCCESS)
987 return; 996 return;
988 997
998 if (result == MigrationResult::NO_NEW_NETWORK) {
999 OnNoNewNetwork();
1000 return;
1001 }
1002
989 // Close the connection if migration failed. Do not cause a 1003 // Close the connection if migration failed. Do not cause a
990 // connection close packet to be sent since socket may be borked. 1004 // connection close packet to be sent since socket may be borked.
991 connection()->CloseConnection(QUIC_PACKET_WRITE_ERROR, 1005 connection()->CloseConnection(QUIC_PACKET_WRITE_ERROR,
992 "Write and subsequent migration failed", 1006 "Write and subsequent migration failed",
993 ConnectionCloseBehavior::SILENT_CLOSE); 1007 ConnectionCloseBehavior::SILENT_CLOSE);
994 } 1008 }
995 1009
1010 void QuicChromiumClientSession::OnNoNewNetwork() {
Ryan Hamilton 2016/09/12 03:42:01 So this is called, obviously, from the write error
Jana 2016/09/12 23:11:01 Yes. It's called only for the DISCONNECTED event,
1011 if (migration_alarm_pending_)
1012 return;
1013 migration_alarm_pending_ = true;
1014
1015 // Block the packet writer to avoid any writes while migration is in progress.
1016 static_cast<QuicChromiumPacketWriter*>(connection()->writer())
1017 ->set_write_blocked(true);
Ryan Hamilton 2016/09/12 03:42:01 I don't understand the motivation for this. What h
Jana 2016/09/12 23:11:01 This causes an NCN notification to block the socke
Ryan Hamilton 2016/09/13 00:33:18 What makes the socket "disconnected" in this case?
Jana 2016/09/13 01:12:18 Something in Android? So this is the case where we
1018
1019 // Post a task to maybe close the session if the alarm fires.
1020 task_runner_->PostDelayedTask(
1021 FROM_HERE, base::Bind(&QuicChromiumClientSession::OnMigrationTimeout,
1022 weak_factory_.GetWeakPtr()),
1023 base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs));
1024 }
1025
996 void QuicChromiumClientSession::WriteToNewSocket() { 1026 void QuicChromiumClientSession::WriteToNewSocket() {
997 // If write_pending_ is false, an earlier task wrote to the new socket. 1027 // If write_pending_ is false, an earlier task wrote to the new socket.
998 if (!write_pending_) 1028 if (!write_pending_)
999 return; 1029 return;
1000 // Prevent any pending migration or write tasks from executing. 1030 // Prevent any pending migration or write tasks from executing.
1001 write_pending_ = false; 1031 write_pending_ = false;
1002 migration_pending_ = false; 1032 migration_pending_ = false;
1003 1033
1004 static_cast<QuicChromiumPacketWriter*>(connection()->writer()) 1034 static_cast<QuicChromiumPacketWriter*>(connection()->writer())
1005 ->set_write_blocked(false); 1035 ->set_write_blocked(false);
(...skipping 24 matching lines...) Expand all
1030 ->WritePacketToSocket(packet); 1060 ->WritePacketToSocket(packet);
1031 1061
1032 if (result.error_code == ERR_IO_PENDING) 1062 if (result.error_code == ERR_IO_PENDING)
1033 return; 1063 return;
1034 // All write errors should be mapped into ERR_IO_PENDING by 1064 // All write errors should be mapped into ERR_IO_PENDING by
1035 // HandleWriteError. 1065 // HandleWriteError.
1036 DCHECK(result.error_code >= 0); 1066 DCHECK(result.error_code >= 0);
1037 connection()->OnCanWrite(); 1067 connection()->OnCanWrite();
1038 } 1068 }
1039 1069
1070 void QuicChromiumClientSession::OnMigrationTimeout() {
1071 if (!migration_alarm_pending_)
1072 return;
Ryan Hamilton 2016/09/12 03:42:01 So does this mean that if multiple timeouts are qu
Jana 2016/09/12 23:11:01 I don't think it matters much, since it's either D
1073 migration_alarm_pending_ = false;
1074 migration_pending_ = false;
1075 write_pending_ = false;
1076 /*
1077 UMA_HISTOGRAM_ENUMERATION(
1078 "Net.QuicSession.ConnectionMigration",
1079 static_cast<int>(MigrationStatus::NO_ALTERNATE_NETWORK),
1080 static_cast<int>(MigrationStatus::MAX));
1081 */
1082 CloseSessionOnError(ERR_NETWORK_CHANGED,
1083 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
1084 }
1085
1086 void QuicChromiumClientSession::OnNetworkConnected(
1087 NetworkChangeNotifier::NetworkHandle network,
1088 const BoundNetLog& bound_net_log) {
1089 // Cancel migration alarm.
1090 migration_alarm_pending_ = false;
1091 // If migration_pending_ is false, an earlier task completed migration.
1092 if (!migration_pending_)
Ryan Hamilton 2016/09/12 03:42:01 With this CL, migration_pending_ is now true both
Jana 2016/09/13 01:12:18 That's correct.
1093 return;
1094 // TODO(jri): Ensure that OnSessionGoingAway is called consistently,
1095 // and that it's always called at the same time in the whole
1096 // migration process. Allows tests to be more uniform.
1097 stream_factory_->OnSessionGoingAway(this);
1098 stream_factory_->MigrateSessionToNewNetwork(
1099 this, network, /*close_session_on_error=*/true, net_log_);
1100 }
1101
1040 void QuicChromiumClientSession::OnWriteError(int error_code) { 1102 void QuicChromiumClientSession::OnWriteError(int error_code) {
1041 DCHECK_NE(ERR_IO_PENDING, error_code); 1103 DCHECK_NE(ERR_IO_PENDING, error_code);
1042 DCHECK_GT(0, error_code); 1104 DCHECK_GT(0, error_code);
1043 connection()->OnWriteError(error_code); 1105 connection()->OnWriteError(error_code);
1044 } 1106 }
1045 1107
1046 void QuicChromiumClientSession::OnWriteUnblocked() { 1108 void QuicChromiumClientSession::OnWriteUnblocked() {
1047 connection()->OnCanWrite(); 1109 connection()->OnCanWrite();
1048 } 1110 }
1049 1111
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 } 1383 }
1322 1384
1323 void QuicChromiumClientSession::DeletePromised( 1385 void QuicChromiumClientSession::DeletePromised(
1324 QuicClientPromisedInfo* promised) { 1386 QuicClientPromisedInfo* promised) {
1325 if (IsOpenStream(promised->id())) 1387 if (IsOpenStream(promised->id()))
1326 streams_pushed_and_claimed_count_++; 1388 streams_pushed_and_claimed_count_++;
1327 QuicClientSessionBase::DeletePromised(promised); 1389 QuicClientSessionBase::DeletePromised(promised);
1328 } 1390 }
1329 1391
1330 } // namespace net 1392 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698