Add a flag to filter out high-cost networks.
This allows webrtc to not gather on cellular networks if wifi or other low cost networks are present. BUG= Review-Url: https://codereview.webrtc.org/1987833002 Cr-Commit-Position: refs/heads/master@{#12979}
This commit is contained in:
parent
8271a7f6d7
commit
603470576e
@ -83,6 +83,7 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
|
||||
LoadClass(jni, "org/webrtc/PeerConnection$IceGatheringState");
|
||||
LoadClass(jni, "org/webrtc/PeerConnection$IceTransportsType");
|
||||
LoadClass(jni, "org/webrtc/PeerConnection$TcpCandidatePolicy");
|
||||
LoadClass(jni, "org/webrtc/PeerConnection$CandidateNetworkPolicy");
|
||||
LoadClass(jni, "org/webrtc/PeerConnection$KeyType");
|
||||
LoadClass(jni, "org/webrtc/PeerConnection$SignalingState");
|
||||
LoadClass(jni, "org/webrtc/RtpReceiver");
|
||||
|
||||
@ -1444,6 +1444,24 @@ JavaTcpCandidatePolicyToNativeType(
|
||||
return PeerConnectionInterface::kTcpCandidatePolicyEnabled;
|
||||
}
|
||||
|
||||
static PeerConnectionInterface::CandidateNetworkPolicy
|
||||
JavaCandidateNetworkPolicyToNativeType(JNIEnv* jni,
|
||||
jobject j_candidate_network_policy) {
|
||||
std::string enum_name =
|
||||
GetJavaEnumName(jni, "org/webrtc/PeerConnection$CandidateNetworkPolicy",
|
||||
j_candidate_network_policy);
|
||||
|
||||
if (enum_name == "ALL")
|
||||
return PeerConnectionInterface::kCandidateNetworkPolicyAll;
|
||||
|
||||
if (enum_name == "LOW_COST")
|
||||
return PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
|
||||
|
||||
RTC_CHECK(false) << "Unexpected CandidateNetworkPolicy enum_name "
|
||||
<< enum_name;
|
||||
return PeerConnectionInterface::kCandidateNetworkPolicyAll;
|
||||
}
|
||||
|
||||
static rtc::KeyType JavaKeyTypeToNativeType(JNIEnv* jni, jobject j_key_type) {
|
||||
std::string enum_name = GetJavaEnumName(
|
||||
jni, "org/webrtc/PeerConnection$KeyType", j_key_type);
|
||||
@ -1529,6 +1547,12 @@ static void JavaRTCConfigurationToJsepRTCConfiguration(
|
||||
jobject j_tcp_candidate_policy = GetObjectField(
|
||||
jni, j_rtc_config, j_tcp_candidate_policy_id);
|
||||
|
||||
jfieldID j_candidate_network_policy_id = GetFieldID(
|
||||
jni, j_rtc_config_class, "candidateNetworkPolicy",
|
||||
"Lorg/webrtc/PeerConnection$CandidateNetworkPolicy;");
|
||||
jobject j_candidate_network_policy = GetObjectField(
|
||||
jni, j_rtc_config, j_candidate_network_policy_id);
|
||||
|
||||
jfieldID j_ice_servers_id = GetFieldID(
|
||||
jni, j_rtc_config_class, "iceServers", "Ljava/util/List;");
|
||||
jobject j_ice_servers = GetObjectField(jni, j_rtc_config, j_ice_servers_id);
|
||||
@ -1561,6 +1585,8 @@ static void JavaRTCConfigurationToJsepRTCConfiguration(
|
||||
JavaRtcpMuxPolicyToNativeType(jni, j_rtcp_mux_policy);
|
||||
rtc_config->tcp_candidate_policy =
|
||||
JavaTcpCandidatePolicyToNativeType(jni, j_tcp_candidate_policy);
|
||||
rtc_config->candidate_network_policy =
|
||||
JavaCandidateNetworkPolicyToNativeType(jni, j_candidate_network_policy);
|
||||
JavaIceServersToJsepIceServers(jni, j_ice_servers, &rtc_config->servers);
|
||||
rtc_config->audio_jitter_buffer_max_packets =
|
||||
GetIntField(jni, j_rtc_config, j_audio_jitter_buffer_max_packets_id);
|
||||
|
||||
@ -116,6 +116,11 @@ public class PeerConnection {
|
||||
ENABLED, DISABLED
|
||||
};
|
||||
|
||||
/** Java version of PeerConnectionInterface.CandidateNetworkPolicy */
|
||||
public enum CandidateNetworkPolicy {
|
||||
ALL, LOW_COST
|
||||
};
|
||||
|
||||
/** Java version of rtc::KeyType */
|
||||
public enum KeyType {
|
||||
RSA, ECDSA
|
||||
@ -133,6 +138,7 @@ public class PeerConnection {
|
||||
public BundlePolicy bundlePolicy;
|
||||
public RtcpMuxPolicy rtcpMuxPolicy;
|
||||
public TcpCandidatePolicy tcpCandidatePolicy;
|
||||
public CandidateNetworkPolicy candidateNetworkPolicy;
|
||||
public int audioJitterBufferMaxPackets;
|
||||
public boolean audioJitterBufferFastAccelerate;
|
||||
public int iceConnectionReceivingTimeout;
|
||||
@ -146,6 +152,7 @@ public class PeerConnection {
|
||||
bundlePolicy = BundlePolicy.BALANCED;
|
||||
rtcpMuxPolicy = RtcpMuxPolicy.NEGOTIATE;
|
||||
tcpCandidatePolicy = TcpCandidatePolicy.ENABLED;
|
||||
candidateNetworkPolicy = candidateNetworkPolicy.ALL;
|
||||
this.iceServers = iceServers;
|
||||
audioJitterBufferMaxPackets = 50;
|
||||
audioJitterBufferFastAccelerate = false;
|
||||
|
||||
@ -2128,6 +2128,12 @@ bool PeerConnection::InitializePortAllocator_n(
|
||||
LOG(LS_INFO) << "TCP candidates are disabled.";
|
||||
}
|
||||
|
||||
if (configuration.candidate_network_policy ==
|
||||
kCandidateNetworkPolicyLowCost) {
|
||||
portallocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
|
||||
LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
|
||||
}
|
||||
|
||||
port_allocator_->set_flags(portallocator_flags);
|
||||
// No step delay is used while allocating ports.
|
||||
port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
|
||||
|
||||
@ -217,6 +217,11 @@ class PeerConnectionInterface : public rtc::RefCountInterface {
|
||||
kTcpCandidatePolicyDisabled
|
||||
};
|
||||
|
||||
enum CandidateNetworkPolicy {
|
||||
kCandidateNetworkPolicyAll,
|
||||
kCandidateNetworkPolicyLowCost
|
||||
};
|
||||
|
||||
enum ContinualGatheringPolicy {
|
||||
GATHER_ONCE,
|
||||
GATHER_CONTINUALLY
|
||||
@ -276,6 +281,8 @@ class PeerConnectionInterface : public rtc::RefCountInterface {
|
||||
BundlePolicy bundle_policy = kBundlePolicyBalanced;
|
||||
RtcpMuxPolicy rtcp_mux_policy = kRtcpMuxPolicyNegotiate;
|
||||
TcpCandidatePolicy tcp_candidate_policy = kTcpCandidatePolicyEnabled;
|
||||
CandidateNetworkPolicy candidate_network_policy =
|
||||
kCandidateNetworkPolicyAll;
|
||||
int audio_jitter_buffer_max_packets = kAudioJitterBufferMaxPackets;
|
||||
bool audio_jitter_buffer_fast_accelerate = false;
|
||||
int ice_connection_receiving_timeout = kUndefined; // ms
|
||||
|
||||
@ -1050,6 +1050,8 @@ TEST_F(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
|
||||
config.disable_ipv6 = true;
|
||||
config.tcp_candidate_policy =
|
||||
PeerConnectionInterface::kTcpCandidatePolicyDisabled;
|
||||
config.candidate_network_policy =
|
||||
PeerConnectionInterface::kCandidateNetworkPolicyLowCost;
|
||||
config.ice_candidate_pool_size = 1;
|
||||
CreatePeerConnection(config, nullptr);
|
||||
|
||||
@ -1060,6 +1062,8 @@ TEST_F(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
|
||||
EXPECT_EQ(1UL, session->stun_servers().size());
|
||||
EXPECT_EQ(0U, session->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6);
|
||||
EXPECT_LT(0U, session->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
|
||||
EXPECT_LT(0U,
|
||||
session->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
|
||||
}
|
||||
|
||||
TEST_F(PeerConnectionInterfaceTest, AddStreams) {
|
||||
|
||||
@ -60,6 +60,16 @@ enum {
|
||||
// Disallow use of UDP when connecting to a relay server. Since proxy servers
|
||||
// usually don't handle UDP, using UDP will leak the IP address.
|
||||
PORTALLOCATOR_DISABLE_UDP_RELAY = 0x1000,
|
||||
|
||||
// When multiple networks exist, do not gather candidates on the ones with
|
||||
// high cost. So if both Wi-Fi and cellular networks exist, gather only on the
|
||||
// Wi-Fi network. If a network type is "unknown", it has a cost lower than
|
||||
// cellular but higher than Wi-Fi/Ethernet. So if an unknown network exists,
|
||||
// cellular networks will not be used to gather candidates and if a Wi-Fi
|
||||
// network is present, "unknown" networks will not be usd to gather
|
||||
// candidates. Doing so ensures that even if a cellular network type was not
|
||||
// detected initially, it would not be used if a Wi-Fi network is present.
|
||||
PORTALLOCATOR_DISABLE_COSTLY_NETWORKS = 0x2000,
|
||||
};
|
||||
|
||||
const uint32_t kDefaultPortAllocatorFlags = 0;
|
||||
|
||||
@ -417,6 +417,19 @@ void BasicPortAllocatorSession::GetNetworks(
|
||||
network->type();
|
||||
}),
|
||||
networks->end());
|
||||
|
||||
if (flags() & PORTALLOCATOR_DISABLE_COSTLY_NETWORKS) {
|
||||
uint16_t lowest_cost = rtc::kNetworkCostMax;
|
||||
for (rtc::Network* network : *networks) {
|
||||
lowest_cost = std::min<uint16_t>(lowest_cost, network->GetCost());
|
||||
}
|
||||
networks->erase(std::remove_if(networks->begin(), networks->end(),
|
||||
[lowest_cost](rtc::Network* network) {
|
||||
return network->GetCost() >
|
||||
lowest_cost + rtc::kNetworkCostLow;
|
||||
}),
|
||||
networks->end());
|
||||
}
|
||||
}
|
||||
|
||||
// For each network, see if we have a sequence that covers it already. If not,
|
||||
|
||||
@ -519,6 +519,53 @@ TEST_F(BasicPortAllocatorTest, TestIgnoreNetworksAccordingToIgnoreMask) {
|
||||
EXPECT_EQ(0x12345602U, candidates_[0].address().ip());
|
||||
}
|
||||
|
||||
// Test that high cost networks are filtered if the flag
|
||||
// PORTALLOCATOR_DISABLE_COSTLY_NETWORKS is set.
|
||||
TEST_F(BasicPortAllocatorTest, TestGatherLowCostNetworkOnly) {
|
||||
SocketAddress addr_wifi(IPAddress(0x12345600U), 0);
|
||||
SocketAddress addr_cellular(IPAddress(0x12345601U), 0);
|
||||
SocketAddress addr_unknown1(IPAddress(0x12345602U), 0);
|
||||
SocketAddress addr_unknown2(IPAddress(0x12345603U), 0);
|
||||
// If both Wi-Fi and cellular interfaces are present, only gather on the Wi-Fi
|
||||
// interface.
|
||||
AddInterface(addr_wifi, "test_wlan0", rtc::ADAPTER_TYPE_WIFI);
|
||||
AddInterface(addr_cellular, "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
|
||||
allocator().set_flags(cricket::PORTALLOCATOR_DISABLE_STUN |
|
||||
cricket::PORTALLOCATOR_DISABLE_RELAY |
|
||||
cricket::PORTALLOCATOR_DISABLE_TCP |
|
||||
cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
|
||||
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
|
||||
session_->StartGettingPorts();
|
||||
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
|
||||
EXPECT_EQ(1U, candidates_.size());
|
||||
EXPECT_TRUE(addr_wifi.EqualIPs(candidates_[0].address()));
|
||||
|
||||
// If both cellular and unknown interfaces are present, only gather on the
|
||||
// unknown interfaces.
|
||||
candidates_.clear();
|
||||
candidate_allocation_done_ = false;
|
||||
RemoveInterface(addr_wifi);
|
||||
AddInterface(addr_unknown1, "test_unknown0", rtc::ADAPTER_TYPE_UNKNOWN);
|
||||
AddInterface(addr_unknown2, "test_unknown1", rtc::ADAPTER_TYPE_UNKNOWN);
|
||||
session_->StartGettingPorts();
|
||||
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
|
||||
EXPECT_EQ(2U, candidates_.size());
|
||||
EXPECT_TRUE((addr_unknown1.EqualIPs(candidates_[0].address()) &&
|
||||
addr_unknown2.EqualIPs(candidates_[1].address())) ||
|
||||
(addr_unknown1.EqualIPs(candidates_[1].address()) &&
|
||||
addr_unknown2.EqualIPs(candidates_[0].address())));
|
||||
|
||||
// If Wi-Fi, cellular, unknown interfaces are all present, only gather on the
|
||||
// Wi-Fi interface.
|
||||
candidates_.clear();
|
||||
candidate_allocation_done_ = false;
|
||||
AddInterface(addr_wifi, "test_wlan0", rtc::ADAPTER_TYPE_WIFI);
|
||||
session_->StartGettingPorts();
|
||||
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
|
||||
EXPECT_EQ(1U, candidates_.size());
|
||||
EXPECT_TRUE(addr_wifi.EqualIPs(candidates_[0].address()));
|
||||
}
|
||||
|
||||
// Tests that we allocator session not trying to allocate ports for every 250ms.
|
||||
TEST_F(BasicPortAllocatorTest, TestNoNetworkInterface) {
|
||||
EXPECT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user