Add field trial to reduce STUN pings.
This patch adds field trials for limiting no of STUN pings
- max_outstanding_pings
send this count of outstanding pings (pings w/o any response),
after that never send any before a reply is received.
NOTE:
1) This patch redoes https://webrtc.googlesource.com/src.git/+/0d28972d8f0659ab90cef7fd59ca54fb122b71bc
which was put into the StunRequestManager.
But that mechanism is not used for STUN pings.
2) This patch build on field-trial-parser added in https://webrtc-review.googlesource.com/c/src/+/156083
Bug: webrtc:10282
Change-Id: If2f22d2b61a28598a3aa93781c9857145576b7a1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156162
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Reviewed-by: Honghai Zhang <honghaiz@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29467}
diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc
index e50890b..1c55619 100644
--- a/p2p/base/connection.cc
+++ b/p2p/base/connection.cc
@@ -1119,6 +1119,18 @@
return waiting > 2 * rtt();
}
+bool Connection::TooManyOutstandingPings(
+ const absl::optional<int>& max_outstanding_pings) const {
+ if (!max_outstanding_pings.has_value()) {
+ return false;
+ }
+ if (static_cast<int>(pings_since_last_response_.size()) <
+ *max_outstanding_pings) {
+ return false;
+ }
+ return true;
+}
+
ProxyConnection::ProxyConnection(Port* port,
size_t index,
const Candidate& remote_candidate)
diff --git a/p2p/base/connection.h b/p2p/base/connection.h
index b872dbf..dc9333d 100644
--- a/p2p/base/connection.h
+++ b/p2p/base/connection.h
@@ -294,6 +294,9 @@
bool stable(int64_t now) const;
+ // Check if we sent |val| pings without receving a response.
+ bool TooManyOutstandingPings(const absl::optional<int>& val) const;
+
protected:
enum { MSG_DELETE = 0, MSG_FIRST_AVAILABLE };
diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index 6e68aa3..a1c1450 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -697,13 +697,19 @@
webrtc::StructParametersParser::Create(
"skip_relay_to_non_relay_connections",
- &field_trials_.skip_relay_to_non_relay_connections)
+ &field_trials_.skip_relay_to_non_relay_connections,
+ "max_outstanding_pings", &field_trials_.max_outstanding_pings)
->Parse(webrtc::field_trial::FindFullName("WebRTC-IceFieldTrials"));
if (field_trials_.skip_relay_to_non_relay_connections) {
RTC_LOG(LS_INFO) << "Set skip_relay_to_non_relay_connections";
}
+ if (field_trials_.max_outstanding_pings.has_value()) {
+ RTC_LOG(LS_INFO) << "Set max_outstanding_pings: "
+ << *field_trials_.max_outstanding_pings;
+ }
+
webrtc::BasicRegatheringController::Config regathering_config(
config_.regather_all_networks_interval_range,
config_.regather_on_failed_networks_interval_or_default());
@@ -1700,6 +1706,7 @@
return b_is_better;
}
}
+
return 0;
}
@@ -2202,6 +2209,12 @@
return false;
}
+ // If we sent a number of pings wo/ reply, skip sending more
+ // until we get one.
+ if (conn->TooManyOutstandingPings(field_trials_.max_outstanding_pings)) {
+ return false;
+ }
+
// If the channel is weakly connected, ping all connections.
if (weak()) {
return true;
diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h
index 1fe68ec..a7a1fbe 100644
--- a/p2p/base/p2p_transport_channel.h
+++ b/p2p/base/p2p_transport_channel.h
@@ -77,6 +77,7 @@
struct IceFieldTrials {
bool skip_relay_to_non_relay_connections = false;
+ absl::optional<int> max_outstanding_pings;
};
// P2PTransportChannel manages the candidates and connection process to keep
diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc
index 1f21bc2..5a060a8 100644
--- a/p2p/base/p2p_transport_channel_unittest.cc
+++ b/p2p/base/p2p_transport_channel_unittest.cc
@@ -4529,6 +4529,29 @@
EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
}
+TEST_F(P2PTransportChannelPingTest, TestMaxOutstandingPingsFieldTrial) {
+ webrtc::test::ScopedFieldTrials field_trials(
+ "WebRTC-IceFieldTrials/max_outstanding_pings:3/");
+ FakePortAllocator pa(rtc::Thread::Current(), nullptr);
+ P2PTransportChannel ch("max", 1, &pa);
+ ch.SetIceConfig(ch.config());
+ PrepareChannel(&ch);
+ ch.MaybeStartGathering();
+ ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
+ ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
+
+ Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
+ Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
+ ASSERT_TRUE(conn1 != nullptr);
+ ASSERT_TRUE(conn2 != nullptr);
+
+ EXPECT_TRUE_WAIT(conn1->num_pings_sent() == 3 && conn2->num_pings_sent() == 3,
+ kDefaultTimeout);
+
+ // Check that these connections don't send any more pings.
+ EXPECT_EQ(nullptr, ch.FindNextPingableConnection());
+}
+
class P2PTransportChannelMostLikelyToWorkFirstTest
: public P2PTransportChannelPingTest {
public: