Add feature to skip RELAY to non-RELAY connections

This patch adds a feature enabled using webrtc field trial
that remove connections between RELAY and non-RELAY candidates.

Bug: webrtc:11021
Change-Id: I924076277a843bffc1d25f6de14d2165f7012c4c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156083
Reviewed-by: Honghai Zhang <honghaiz@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29464}
This commit is contained in:
Jonas Oreland 2019-10-11 08:17:06 +02:00 committed by Commit Bot
parent 0deef725b9
commit 4af78823fa
4 changed files with 48 additions and 0 deletions

View File

@ -106,6 +106,7 @@ rtc_static_library("rtc_p2p") {
"../logging:ice_log",
"../rtc_base",
"../rtc_base:checks",
"../rtc_base/experiments:field_trial_parser",
"//third_party/abseil-cpp/absl/memory",
# Needed by pseudo_tcp, which should move to a separate target.

View File

@ -23,6 +23,7 @@
#include "p2p/base/port.h"
#include "rtc_base/checks.h"
#include "rtc_base/crc32.h"
#include "rtc_base/experiments/struct_parameters_parser.h"
#include "rtc_base/logging.h"
#include "rtc_base/net_helper.h"
#include "rtc_base/net_helpers.h"
@ -694,6 +695,15 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
RTC_LOG(LS_INFO) << "Set WebRTC-TurnAddMultiMapping: Enabled";
}
webrtc::StructParametersParser::Create(
"skip_relay_to_non_relay_connections",
&field_trials_.skip_relay_to_non_relay_connections)
->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";
}
webrtc::BasicRegatheringController::Config regathering_config(
config_.regather_all_networks_interval_range,
config_.regather_on_failed_networks_interval_or_default());
@ -1323,6 +1333,17 @@ bool P2PTransportChannel::CreateConnection(PortInterface* port,
if (!port->SupportsProtocol(remote_candidate.protocol())) {
return false;
}
if (field_trials_.skip_relay_to_non_relay_connections) {
if ((port->Type() != remote_candidate.type()) &&
(port->Type() == RELAY_PORT_TYPE ||
remote_candidate.type() == RELAY_PORT_TYPE)) {
RTC_LOG(LS_INFO) << ToString() << ": skip creating connection "
<< port->Type() << " to " << remote_candidate.type();
return false;
}
}
// Look for an existing connection with this remote address. If one is not
// found or it is found but the existing remote candidate has an older
// generation, then we can create a new connection for this address.

View File

@ -75,6 +75,10 @@ class RemoteCandidate : public Candidate {
PortInterface* origin_port_;
};
struct IceFieldTrials {
bool skip_relay_to_non_relay_connections = false;
};
// P2PTransportChannel manages the candidates and connection process to keep
// two P2P clients connected to each other.
class RTC_EXPORT P2PTransportChannel : public IceTransportInternal {
@ -501,6 +505,8 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal {
// Number of times the selected_connection_ has been modified.
uint32_t selected_candidate_pair_changes_ = 0;
IceFieldTrials field_trials_;
RTC_DISALLOW_COPY_AND_ASSIGN(P2PTransportChannel);
};

View File

@ -4705,6 +4705,26 @@ TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
}
// Test skip_relay_to_non_relay_connections field-trial.
// I.e that we never create connection between relay and non-relay.
TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
TestSkipRelayToNonRelayConnectionsFieldTrial) {
webrtc::test::ScopedFieldTrials field_trials(
"WebRTC-IceFieldTrials/skip_relay_to_non_relay_connections:true/");
P2PTransportChannel& ch = StartTransportChannel(true, 500);
EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
// Remote Relay candidate arrives.
ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
EXPECT_TRUE_WAIT(ch.connections().size() == 1, kDefaultTimeout);
// Remote Local candidate arrives.
ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);
}
// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
// followed by the rest.
TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {