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

Unified Diff: webrtc/p2p/base/p2ptransportchannel.cc

Issue 2369963004: Ping the premier connection on each network with higher priority. (Closed)
Patch Set: . Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/p2p/base/p2ptransportchannel.cc
diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc
index 3f68d6d6e078fd635e8f696b3b46ae12bae8ce67..25bcebebcebd8f8407611c086986adb5a5df8fca 100644
--- a/webrtc/p2p/base/p2ptransportchannel.cc
+++ b/webrtc/p2p/base/p2ptransportchannel.cc
@@ -1248,6 +1248,8 @@ void P2PTransportChannel::SortConnectionsAndUpdateState() {
// have higher priority if it is writable.
MaybeSwitchSelectedConnection(top_connection, "sorting");
+ UpdatePremierConnections();
+
// The controlled side can prune only if the selected connection has been
// nominated because otherwise it may prune the connection that will be
// selected by the controlling side.
@@ -1285,6 +1287,21 @@ void P2PTransportChannel::SortConnectionsAndUpdateState() {
MaybeStartPinging();
}
+void P2PTransportChannel::UpdatePremierConnections() {
+ // |connections_| has been sorted, so the first one in the list on a given
+ // network is the premier connection, except that the selected connection
+ // is always the premier connection on the network.
+ premier_connection_by_network_name_.clear();
+ for (Connection* conn : connections_) {
+ const std::string& network_name = conn->port()->Network()->name();
+ if (conn == selected_connection_ ||
+ premier_connection_by_network_name_.find(network_name) ==
+ premier_connection_by_network_name_.end()) {
+ premier_connection_by_network_name_[network_name] = conn;
+ }
+ }
+}
+
void P2PTransportChannel::PruneConnections() {
// We can prune any connection for which there is a connected, writable
// connection on the same network with better or equal priority. We leave
@@ -1295,25 +1312,16 @@ void P2PTransportChannel::PruneConnections() {
// switch. If the |premier| connection is not connected, we may be
// reconnecting a TCP connection and temporarily do not prune connections in
// this network. See the big comment in CompareConnectionStates.
-
- // Get a list of the networks that we are using.
- std::set<rtc::Network*> networks;
- for (const Connection* conn : connections_) {
- networks.insert(conn->port()->Network());
- }
- for (rtc::Network* network : networks) {
- Connection* premier = GetBestConnectionOnNetwork(network);
- // Do not prune connections if the current selected connection is weak on
+ for (Connection* conn : connections_) {
+ // Do not prune connections if the current premier connection is weak on
// this network. Otherwise, it may delete connections prematurely.
- if (!premier || premier->weak()) {
+ Connection* premier =
+ premier_connection_by_network_name_[conn->port()->Network()->name()];
+ if (!premier || conn == premier || premier->weak()) {
continue;
}
-
- for (Connection* conn : connections_) {
- if ((conn != premier) && (conn->port()->Network() == network) &&
- (CompareConnectionCandidates(premier, conn) >= 0)) {
- conn->Prune();
- }
+ if (CompareConnectionCandidates(premier, conn) >= 0) {
+ conn->Prune();
}
}
}
@@ -1451,26 +1459,6 @@ bool P2PTransportChannel::ReadyToSend(Connection* connection) const {
PresumedWritable(connection));
}
-// If we have a selected connection, return it, otherwise return top one in the
-// list (later we will mark it best).
-Connection* P2PTransportChannel::GetBestConnectionOnNetwork(
- rtc::Network* network) const {
- // If the selected connection is on this network, then it wins.
- if (selected_connection_ &&
- (selected_connection_->port()->Network() == network)) {
- return selected_connection_;
- }
-
- // Otherwise, we return the top-most in sorted order.
- for (size_t i = 0; i < connections_.size(); ++i) {
- if (connections_[i]->port()->Network() == network) {
- return connections_[i];
- }
- }
-
- return NULL;
-}
-
// Handle any queued up requests
void P2PTransportChannel::OnMessage(rtc::Message *pmsg) {
switch (pmsg->message_id) {
@@ -1548,19 +1536,26 @@ bool P2PTransportChannel::IsPingable(const Connection* conn,
return false;
}
- // If the channel is weakly connected, ping all connections.
- if (weak()) {
- return true;
- }
-
- // Always ping active connections regardless whether the channel is completed
- // or not, but backup connections are pinged at a slower rate.
- if (IsBackupConnection(conn)) {
+ // Backup connections are pinged at a slower rate if the channel is strongly
+ // connected.
+ bool strongly_connected = !weak();
+ if (strongly_connected && IsBackupConnection(conn)) {
return conn->rtt_samples() == 0 ||
(now >= conn->last_ping_response_received() +
config_.backup_connection_ping_interval);
}
- // Don't ping inactive non-backup connections.
+
+ // If the premier connection is weakly connected, ping all connections on
Taylor Brandstetter 2016/10/04 02:08:10 Suggest changing this to "If the premier connectio
honghaiz3 2016/10/20 23:47:58 Done.
+ // the same network. Otherwise, do not ping those with a lower priority
+ // (i.e., those having been pruned) or those which have timed out.
+ auto iter =
+ premier_connection_by_network_name_.find(conn->port()->Network()->name());
+ if (iter == premier_connection_by_network_name_.end() || !iter->second ||
+ iter->second->weak()) {
+ return true;
+ }
+
+ // Don't ping inactive connections.
if (!conn->active()) {
return false;
}
@@ -1576,14 +1571,41 @@ bool P2PTransportChannel::IsPingable(const Connection* conn,
return (now >= conn->last_ping_sent() + ping_interval);
}
-bool P2PTransportChannel::IsSelectedConnectionPingable(int64_t now) {
- if (!selected_connection_ || !selected_connection_->connected() ||
- !selected_connection_->writable()) {
+bool P2PTransportChannel::IsPremierConnectionPingable(
+ Connection* premier_connection,
+ int64_t now) {
+ if (!premier_connection || !premier_connection->connected() ||
+ !premier_connection->writable() ||
+ premier_connection->state() == Connection::STATE_FAILED) {
Taylor Brandstetter 2016/10/04 02:08:09 Why did the "failed" check not exist before?
honghaiz3 2016/10/20 23:47:58 It is logical to include this although it does not
return false;
}
- int interval = CalculateActiveWritablePingInterval(selected_connection_, now);
- return selected_connection_->last_ping_sent() + interval <= now;
+ int interval = CalculateActiveWritablePingInterval(premier_connection, now);
+ return premier_connection->last_ping_sent() + interval <= now;
+}
+
+Connection* P2PTransportChannel::FindBestPremierConnectionToPing(int64_t now) {
+ // If the selected connection is pingable, select it to ping.
+ if (IsPremierConnectionPingable(selected_connection_, now)) {
+ return selected_connection_;
+ }
+
+ // Otherwise, find the premier connection that has not been pinged for the
+ // longest time.
+ Connection* oldest_premier_connection = nullptr;
+ for (auto kv : premier_connection_by_network_name_) {
+ Connection* conn = kv.second;
+ if (conn == nullptr || conn == selected_connection_) {
+ continue;
+ }
+ if (IsPremierConnectionPingable(conn, now) &&
+ (!oldest_premier_connection ||
+ conn->last_ping_sent() <
+ oldest_premier_connection->last_ping_sent())) {
+ oldest_premier_connection = conn;
+ }
+ }
+ return oldest_premier_connection;
}
int P2PTransportChannel::CalculateActiveWritablePingInterval(
@@ -1598,8 +1620,9 @@ int P2PTransportChannel::CalculateActiveWritablePingInterval(
int stable_interval = config_.stable_writable_connection_ping_interval;
int stablizing_interval =
std::min(stable_interval, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
-
- return conn->stable(now) ? stable_interval : stablizing_interval;
+ // If the channel is weak or the connection is not stable yet, use the
+ // stablizing_interval.
+ return (!weak() && conn->stable(now)) ? stable_interval : stablizing_interval;
Taylor Brandstetter 2016/10/04 02:08:09 So this is now the "stabilizing or weak" interval?
honghaiz3 2016/10/20 23:47:58 Changed to weak_or_stablizing_interval.
}
// Returns the next pingable connection to ping. This will be the oldest
@@ -1611,10 +1634,8 @@ int P2PTransportChannel::CalculateActiveWritablePingInterval(
// CompareConnectionStates.
Connection* P2PTransportChannel::FindNextPingableConnection() {
int64_t now = rtc::TimeMillis();
- Connection* conn_to_ping = nullptr;
- if (IsSelectedConnectionPingable(now)) {
- conn_to_ping = selected_connection_;
- } else {
+ Connection* conn_to_ping = FindBestPremierConnectionToPing(now);
+ if (!conn_to_ping) {
conn_to_ping = FindConnectionToPing(now);
}
return conn_to_ping;
@@ -1728,9 +1749,16 @@ void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) {
pinged_connections_.erase(*iter);
unpinged_connections_.erase(*iter);
connections_.erase(iter);
+ for (auto kv : premier_connection_by_network_name_) {
+ if (kv.second == connection) {
+ kv.second = nullptr;
+ }
+ }
- LOG_J(LS_INFO, this) << "Removed connection ("
- << static_cast<int>(connections_.size()) << " remaining)";
+ LOG_J(LS_INFO, this) << "Removed connection " << std::hex << connection
Taylor Brandstetter 2016/10/04 02:08:10 Why not log connection->ToString()?
honghaiz3 2016/10/20 23:47:58 connection->ToString() needs to access the members
Taylor Brandstetter 2016/10/21 20:18:49 Does that risk really exist? I thought a Port is o
honghaiz3 2016/10/21 21:27:26 It probably does not although it would require car
+ << std::dec << " ("
+ << static_cast<int>(connections_.size())
+ << " remaining)";
// If this is currently the selected connection, then we need to pick a new
// one. The call to SortConnectionsAndUpdateState will pick a new one. It
@@ -1858,7 +1886,7 @@ void P2PTransportChannel::OnReadyToSend(Connection* connection) {
// Find "triggered checks". We ping first those connections that have
// received a ping but have not sent a ping since receiving it
-// (last_received_ping > last_sent_ping). But we shouldn't do
+// (last_ping_received > last_ping_sent). But we shouldn't do
// triggered checks if the connection is already writable.
Connection* P2PTransportChannel::FindOldestConnectionNeedingTriggeredCheck(
int64_t now) {

Powered by Google App Engine
This is Rietveld 408576698