Fix problem with ipv4 over ipv6 on Android

This patch fixes a problem with using ipv4 over ipv6
addresses on Android. These addresses are discovered
using 'getifaddr' with interfaces called 'v4-wlan0' or
'v4-rmnet' but the Android API does not report them.

This leads to failure when BasicPortAllocator tries
to bind a socket to the ip-address, making the ipv4
address unusable.

This solution does the following
1) Insert BasicNetworkManager as NetworkBinderInterface
rather than AndroidNetworkManager.

2) When SocketServer calls BindSocketToNetwork,
BasicNetworkManager first lookup the interface name,
and then calls AndroidNetworkManager.

3) AndroidNetworkManager will then first try to bind
using the known ip-addresses, and if it can't find the network
it will instead match the interface names.

The patch has been tested on real android devices, and works fine.
And everything is disabled by default, and is enabled by field trial.

My plan is to rollout the feature, checking that it does not introduce
any problems, and if so, enabled for all.

Bug: webrtc:10707
Change-Id: I7081ba43d4ce17077acfa5fbab44eda127ac3971
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/211003
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33422}
This commit is contained in:
Jonas Oreland
2021-03-10 15:33:31 +01:00
committed by Commit Bot
parent 89cb65ed66
commit da2fd2a2b2
7 changed files with 242 additions and 37 deletions

View File

@ -69,7 +69,7 @@ TEST_F(AndroidNetworkMonitorTest, TestFindNetworkHandleUsingIpv4Address) {
network_monitor_->SetNetworkInfos(net_infos);
auto network_handle =
network_monitor_->FindNetworkHandleFromAddress(ipv4_address);
network_monitor_->FindNetworkHandleFromAddressOrName(ipv4_address, "");
ASSERT_TRUE(network_handle.has_value());
EXPECT_EQ(ipv4_handle, *network_handle);
@ -86,9 +86,9 @@ TEST_F(AndroidNetworkMonitorTest, TestFindNetworkHandleUsingFullIpv6Address) {
network_monitor_->SetNetworkInfos(net_infos);
auto network_handle1 =
network_monitor_->FindNetworkHandleFromAddress(ipv6_address1);
network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address1, "");
auto network_handle2 =
network_monitor_->FindNetworkHandleFromAddress(ipv6_address2);
network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address2, "");
ASSERT_TRUE(network_handle1.has_value());
EXPECT_EQ(ipv6_handle, *network_handle1);
@ -111,9 +111,9 @@ TEST_F(AndroidNetworkMonitorTest,
network_monitor_->SetNetworkInfos(net_infos);
auto network_handle1 =
network_monitor_->FindNetworkHandleFromAddress(ipv6_address1);
network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address1, "");
auto network_handle2 =
network_monitor_->FindNetworkHandleFromAddress(ipv6_address2);
network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address2, "");
ASSERT_TRUE(network_handle1.has_value());
EXPECT_EQ(ipv6_handle, *network_handle1);
@ -121,5 +121,33 @@ TEST_F(AndroidNetworkMonitorTest,
EXPECT_EQ(ipv6_handle, *network_handle2);
}
TEST_F(AndroidNetworkMonitorTest, TestFindNetworkHandleUsingIfName) {
ScopedFieldTrials field_trials("WebRTC-BindUsingInterfaceName/Enabled/");
// Start() updates the states introduced by the field trial.
network_monitor_->Start();
jni::NetworkHandle ipv6_handle = 200;
rtc::IPAddress ipv6_address1 = GetIpAddressFromIpv6String(kTestIpv6Address1);
// Set up an IPv6 network.
jni::NetworkInformation net_info =
CreateNetworkInformation("wlan0", ipv6_handle, ipv6_address1);
std::vector<jni::NetworkInformation> net_infos(1, net_info);
network_monitor_->SetNetworkInfos(net_infos);
rtc::IPAddress ipv4_address(kTestIpv4Address);
// Search using ip address only...
auto network_handle1 =
network_monitor_->FindNetworkHandleFromAddressOrName(ipv4_address, "");
// Search using ip address AND if_name (for typical ipv4 over ipv6 tunnel).
auto network_handle2 = network_monitor_->FindNetworkHandleFromAddressOrName(
ipv4_address, "v4-wlan0");
ASSERT_FALSE(network_handle1.has_value());
ASSERT_TRUE(network_handle2.has_value());
EXPECT_EQ(ipv6_handle, *network_handle2);
}
} // namespace test
} // namespace webrtc