Skip to content

Commit

Permalink
Close non-migratable streams but migrate the rest of the steams when …
Browse files Browse the repository at this point in the history
…QUIC connection migration migrates to an alternate network.

Bug: 791886
Change-Id: Idf803b0e7453ffc1ef44de3209e7cda74e58f64d
Reviewed-on: https://chromium-review.googlesource.com/1125525
Commit-Queue: Zhongyi Shi <zhongyi@chromium.org>
Reviewed-by: Ryan Hamilton <rch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574075}
  • Loading branch information
zyshi authored and Commit Bot committed Jul 11, 2018
1 parent a450d72 commit 0439ecc
Show file tree
Hide file tree
Showing 3 changed files with 456 additions and 15 deletions.
53 changes: 42 additions & 11 deletions net/quic/chromium/quic_chromium_client_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1769,6 +1769,16 @@ void QuicChromiumClientSession::OnProbeNetworkSucceeded(
writer->set_delegate(this);
connection()->SetSelfAddress(self_address);

// Close streams that are not migratable to the probed |network|.
// If session then becomes idle, close the connection.
ResetNonMigratableStreams();
if (GetNumActiveStreams() == 0 && GetNumDrainingStreams() == 0) {
CloseSessionOnErrorLater(
ERR_NETWORK_CHANGED,
quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
return;
}

// Migrate to the probed socket immediately: socket, writer and reader will
// be acquired by connection and used as default on success.
if (!MigrateToSocket(std::move(socket), std::move(reader),
Expand Down Expand Up @@ -2369,20 +2379,26 @@ bool QuicChromiumClientSession::IsSessionMigratable(
}
return false;
}
return true;
}

// Do not migrate sessions with non-migratable streams.
if (HasNonMigratableStreams()) {
if (close_session_if_not_migratable) {
HistogramAndLogMigrationFailure(net_log_,
MIGRATION_STATUS_NON_MIGRATABLE_STREAM,
connection_id(), "Non-migratable stream");
CloseSessionOnErrorLater(
ERR_NETWORK_CHANGED,
quic::QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM);
void QuicChromiumClientSession::ResetNonMigratableStreams() {
// TODO(zhongyi): may close non-migratable draining streams as well to avoid
// sending additional data on alternate networks.
auto it = dynamic_streams().begin();
// Stream may be deleted when iterating through the map.
while (it != dynamic_streams().end()) {
QuicChromiumClientStream* stream =
static_cast<QuicChromiumClientStream*>(it->second.get());
if (!stream->can_migrate()) {
// Close the stream in both direction by resetting the stream.
// TODO(zhongyi): use a different error code to reset streams for
// connection migration.
stream->Reset(quic::QUIC_STREAM_CANCELLED);
} else {
it++;
}
return false;
}
return true;
}

void QuicChromiumClientSession::LogMetricsOnNetworkDisconnected() {
Expand Down Expand Up @@ -2607,6 +2623,21 @@ MigrationResult QuicChromiumClientSession::Migrate(
if (!stream_factory_)
return MigrationResult::FAILURE;

if (network != NetworkChangeNotifier::kInvalidNetworkHandle) {
// This is a migration attempt from connection migration. Close
// streams that are not migratable to |network|. If session then becomes
// idle, close the connection if |close_session_on_error| is true.
ResetNonMigratableStreams();
if (GetNumActiveStreams() == 0 && GetNumDrainingStreams() == 0) {
if (close_session_on_error) {
CloseSessionOnErrorLater(
ERR_NETWORK_CHANGED,
quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
}
return MigrationResult::FAILURE;
}
}

// Create and configure socket on |network|.
std::unique_ptr<DatagramClientSocket> socket(
stream_factory_->CreateSocket(net_log_.net_log(), net_log_.source()));
Expand Down
4 changes: 4 additions & 0 deletions net/quic/chromium/quic_chromium_client_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,10 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// Returns true if session is migratable. If not, a task is posted to
// close the session later if |close_session_if_not_migratable| is true.
bool IsSessionMigratable(bool close_session_if_not_migratable);
// Close non-migratable streams in both directions by sending reset stream to
// peer when connection migration attempts to migrate to the alternate
// network.
void ResetNonMigratableStreams();
void LogMetricsOnNetworkDisconnected();
void LogMetricsOnNetworkMadeDefault();
void LogConnectionMigrationResultToHistogram(
Expand Down
Loading

0 comments on commit 0439ecc

Please sign in to comment.