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:
committed by
Commit Bot
parent
89cb65ed66
commit
da2fd2a2b2
@ -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
|
||||
|
||||
Reference in New Issue
Block a user