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)(