From b09b3f9a6202e8bcbd8f3e12af1257a1d00cc5a0 Mon Sep 17 00:00:00 2001 From: zhihuang Date: Tue, 7 Mar 2017 14:40:51 -0800 Subject: [PATCH] Add the option to disable IPv6 ICE candidates on WiFi. Add an attribute to the RTCConfiguration which can be used by specific mobile devices so that the IPv6 ICE candidates on WiFi will not be collected. BUG=b/35725283 Review-Url: https://codereview.webrtc.org/2731813002 Cr-Commit-Position: refs/heads/master@{#17100} --- webrtc/api/peerconnectioninterface.h | 6 ++++++ webrtc/p2p/base/p2ptransportchannel_unittest.cc | 12 ++++++++---- webrtc/p2p/base/portallocator.h | 3 +++ webrtc/p2p/client/basicportallocator.cc | 7 +++++++ webrtc/p2p/client/basicportallocator_unittest.cc | 6 +++--- webrtc/pc/peerconnection.cc | 10 +++++++++- .../sdk/android/api/org/webrtc/PeerConnection.java | 2 ++ webrtc/sdk/android/src/jni/peerconnection_jni.cc | 5 +++++ 8 files changed, 43 insertions(+), 8 deletions(-) diff --git a/webrtc/api/peerconnectioninterface.h b/webrtc/api/peerconnectioninterface.h index 165f2d5a00..d9d6c89e29 100644 --- a/webrtc/api/peerconnectioninterface.h +++ b/webrtc/api/peerconnectioninterface.h @@ -332,6 +332,12 @@ class PeerConnectionInterface : public rtc::RefCountInterface { // experimental bool disable_ipv6 = false; + // If set to true, don't gather IPv6 ICE candidates on Wi-Fi. + // Only intended to be used on specific devices. Certain phones disable IPv6 + // when the screen is turned off and it would be better to just disable the + // IPv6 ICE candidates on Wi-Fi in those cases. + bool disable_ipv6_on_wifi = false; + // If set to true, use RTP data channels instead of SCTP. // TODO(deadbeef): Remove this. We no longer commit to supporting RTP data // channels, though some applications are still working on moving off of diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc index da0bfb0414..b891f01e61 100644 --- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc +++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc @@ -1650,8 +1650,10 @@ TEST_F(P2PTransportChannelTest, TestIPv6Connections) { SetAllocationStepDelay(1, kMinimumStepDelay); // Enable IPv6 - SetAllocatorFlags(0, PORTALLOCATOR_ENABLE_IPV6); - SetAllocatorFlags(1, PORTALLOCATOR_ENABLE_IPV6); + SetAllocatorFlags( + 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); + SetAllocatorFlags( + 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); CreateChannels(); @@ -2196,8 +2198,10 @@ TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) { GetAllocator(0)->AddTurnServer(turn_server); GetAllocator(1)->AddTurnServer(turn_server); // Enable IPv6 - SetAllocatorFlags(0, PORTALLOCATOR_ENABLE_IPV6); - SetAllocatorFlags(1, PORTALLOCATOR_ENABLE_IPV6); + SetAllocatorFlags( + 0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); + SetAllocatorFlags( + 1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); SetAllocationStepDelay(0, kMinimumStepDelay); SetAllocationStepDelay(1, kMinimumStepDelay); diff --git a/webrtc/p2p/base/portallocator.h b/webrtc/p2p/base/portallocator.h index 016a7dc996..eb7308cb36 100644 --- a/webrtc/p2p/base/portallocator.h +++ b/webrtc/p2p/base/portallocator.h @@ -73,6 +73,9 @@ enum { // 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, + + // When specified, do not collect IPv6 ICE candidates on Wi-Fi. + PORTALLOCATOR_ENABLE_IPV6_ON_WIFI = 0x4000, }; // Defines various reasons that have caused ICE regathering. diff --git a/webrtc/p2p/client/basicportallocator.cc b/webrtc/p2p/client/basicportallocator.cc index 49ab142d46..d76ff565a6 100644 --- a/webrtc/p2p/client/basicportallocator.cc +++ b/webrtc/p2p/client/basicportallocator.cc @@ -610,6 +610,13 @@ void BasicPortAllocatorSession::DoAllocate() { continue; } + if (!(sequence_flags & PORTALLOCATOR_ENABLE_IPV6_ON_WIFI) && + networks[i]->GetBestIP().family() == AF_INET6 && + networks[i]->type() == rtc::ADAPTER_TYPE_WIFI) { + // Skip IPv6 Wi-Fi networks unless the flag's been set. + continue; + } + // Disable phases that would only create ports equivalent to // ones that we have already made. DisableEquivalentPhases(networks[i], config, &sequence_flags); diff --git a/webrtc/p2p/client/basicportallocator_unittest.cc b/webrtc/p2p/client/basicportallocator_unittest.cc index 7bba15b155..9b2146980f 100644 --- a/webrtc/p2p/client/basicportallocator_unittest.cc +++ b/webrtc/p2p/client/basicportallocator_unittest.cc @@ -639,9 +639,9 @@ class BasicPortAllocatorTest : public FakeClockBase, AddTurnServers(kTurnUdpIntIPv6Addr, kTurnTcpIntIPv6Addr); allocator_->set_step_delay(kMinimumStepDelay); - allocator_->set_flags(allocator().flags() | - PORTALLOCATOR_ENABLE_SHARED_SOCKET | - PORTALLOCATOR_ENABLE_IPV6); + allocator_->set_flags( + allocator().flags() | PORTALLOCATOR_ENABLE_SHARED_SOCKET | + PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); EXPECT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP)); session_->StartGettingPorts(); EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, diff --git a/webrtc/pc/peerconnection.cc b/webrtc/pc/peerconnection.cc index 665bb97cd4..3f01d69edf 100644 --- a/webrtc/pc/peerconnection.cc +++ b/webrtc/pc/peerconnection.cc @@ -477,6 +477,7 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( bool prioritize_most_likely_ice_candidate_pairs; struct cricket::MediaConfig media_config; bool disable_ipv6; + bool disable_ipv6_on_wifi; bool enable_rtp_data_channel; bool enable_quic; rtc::Optional screencast_min_bitrate; @@ -509,6 +510,7 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( prioritize_most_likely_ice_candidate_pairs == o.prioritize_most_likely_ice_candidate_pairs && media_config == o.media_config && disable_ipv6 == o.disable_ipv6 && + disable_ipv6_on_wifi == o.disable_ipv6_on_wifi && enable_rtp_data_channel == o.enable_rtp_data_channel && enable_quic == o.enable_quic && screencast_min_bitrate == o.screencast_min_bitrate && @@ -2505,7 +2507,8 @@ bool PeerConnection::InitializePortAllocator_n( // enable BUNDLE here. int portallocator_flags = port_allocator_->flags(); portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET | - cricket::PORTALLOCATOR_ENABLE_IPV6; + cricket::PORTALLOCATOR_ENABLE_IPV6 | + cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI; // If the disable-IPv6 flag was specified, we'll not override it // by experiment. if (configuration.disable_ipv6) { @@ -2515,6 +2518,11 @@ bool PeerConnection::InitializePortAllocator_n( portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6); } + if (configuration.disable_ipv6_on_wifi) { + portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); + LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled."; + } + if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) { portallocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP; LOG(LS_INFO) << "TCP candidates are disabled."; diff --git a/webrtc/sdk/android/api/org/webrtc/PeerConnection.java b/webrtc/sdk/android/api/org/webrtc/PeerConnection.java index 784b590c08..4e91a1141c 100644 --- a/webrtc/sdk/android/api/org/webrtc/PeerConnection.java +++ b/webrtc/sdk/android/api/org/webrtc/PeerConnection.java @@ -161,6 +161,7 @@ public class PeerConnection { public boolean pruneTurnPorts; public boolean presumeWritableWhenFullyRelayed; public Integer iceCheckMinInterval; + public boolean disableIPv6OnWifi; public RTCConfiguration(List iceServers) { iceTransportsType = IceTransportsType.ALL; @@ -179,6 +180,7 @@ public class PeerConnection { pruneTurnPorts = false; presumeWritableWhenFullyRelayed = false; iceCheckMinInterval = null; + disableIPv6OnWifi = false; } }; diff --git a/webrtc/sdk/android/src/jni/peerconnection_jni.cc b/webrtc/sdk/android/src/jni/peerconnection_jni.cc index dfc1090463..e28641a54d 100644 --- a/webrtc/sdk/android/src/jni/peerconnection_jni.cc +++ b/webrtc/sdk/android/src/jni/peerconnection_jni.cc @@ -1796,6 +1796,9 @@ static void JavaRTCConfigurationToJsepRTCConfiguration( jclass j_integer_class = jni->FindClass("java/lang/Integer"); jmethodID int_value_id = GetMethodID(jni, j_integer_class, "intValue", "()I"); + jfieldID j_disable_ipv6_on_wifi_id = + GetFieldID(jni, j_rtc_config_class, "disableIPv6OnWifi", "Z"); + rtc_config->type = JavaIceTransportsTypeToNativeType(jni, j_ice_transports_type); rtc_config->bundle_policy = @@ -1832,6 +1835,8 @@ static void JavaRTCConfigurationToJsepRTCConfiguration( rtc_config->ice_check_min_interval = rtc::Optional(ice_check_min_interval_value); } + rtc_config->disable_ipv6_on_wifi = + GetBooleanField(jni, j_rtc_config, j_disable_ipv6_on_wifi_id); } JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnection)(