Modify GetBestIP to prefer global IPv6 addresses to the link local IPv6 addresses.

The change is behind the flag WebRTC-PreferGlobalIPv6ToLinkLocal.

Bug: webrtc:14306
Change-Id: Id2cae2e510fcfd007016e79ae4bd46947101d0fc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/269762
Commit-Queue: Diep Bui <diepbp@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37658}
diff --git a/rtc_base/network_unittest.cc b/rtc_base/network_unittest.cc
index a8152fd..1b8463e 100644
--- a/rtc_base/network_unittest.cc
+++ b/rtc_base/network_unittest.cc
@@ -339,9 +339,11 @@
 
 TEST_F(NetworkTest, TestIsIgnoredNetworkIgnoresIPsStartingWith0) {
   Network ipv4_network1("test_eth0", "Test Network Adapter 1",
-                        IPAddress(0x12345600U), 24, ADAPTER_TYPE_ETHERNET);
+                        IPAddress(0x12345600U), 24, ADAPTER_TYPE_ETHERNET,
+                        &field_trials_);
   Network ipv4_network2("test_eth1", "Test Network Adapter 2",
-                        IPAddress(0x010000U), 24, ADAPTER_TYPE_ETHERNET);
+                        IPAddress(0x010000U), 24, ADAPTER_TYPE_ETHERNET,
+                        &field_trials_);
   PhysicalSocketServer socket_server;
   BasicNetworkManager network_manager(&socket_server);
   network_manager.StartUpdating();
@@ -821,19 +823,19 @@
 
 TEST_F(NetworkTest, TestNetworkAdapterTypes) {
   Network wifi("wlan0", "Wireless Adapter", IPAddress(0x12345600U), 24,
-               ADAPTER_TYPE_WIFI);
+               ADAPTER_TYPE_WIFI, &field_trials_);
   EXPECT_EQ(ADAPTER_TYPE_WIFI, wifi.type());
   Network ethernet("eth0", "Ethernet", IPAddress(0x12345600U), 24,
-                   ADAPTER_TYPE_ETHERNET);
+                   ADAPTER_TYPE_ETHERNET, &field_trials_);
   EXPECT_EQ(ADAPTER_TYPE_ETHERNET, ethernet.type());
   Network cellular("test_cell", "Cellular Adapter", IPAddress(0x12345600U), 24,
-                   ADAPTER_TYPE_CELLULAR);
+                   ADAPTER_TYPE_CELLULAR, &field_trials_);
   EXPECT_EQ(ADAPTER_TYPE_CELLULAR, cellular.type());
   Network vpn("bridge_test", "VPN Adapter", IPAddress(0x12345600U), 24,
-              ADAPTER_TYPE_VPN);
+              ADAPTER_TYPE_VPN, &field_trials_);
   EXPECT_EQ(ADAPTER_TYPE_VPN, vpn.type());
   Network unknown("test", "Test Adapter", IPAddress(0x12345600U), 24,
-                  ADAPTER_TYPE_UNKNOWN);
+                  ADAPTER_TYPE_UNKNOWN, &field_trials_);
   EXPECT_EQ(ADAPTER_TYPE_UNKNOWN, unknown.type());
 }
 
@@ -1153,6 +1155,69 @@
   EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
 }
 
+// Test that the filtering logic follows the defined ruleset in network.h.
+TEST_F(NetworkTest, TestGetBestIPWithPreferGlobalIPv6ToLinkLocalEnabled) {
+  webrtc::test::ScopedKeyValueConfig field_trials(
+      "WebRTC-PreferGlobalIPv6ToLinkLocal/Enabled/");
+  InterfaceAddress ip, link_local;
+  std::string ipstr;
+
+  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c3";
+  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_DEPRECATED, &ip));
+
+  // Create a network with this prefix.
+  Network ipv6_network("test_eth0", "Test NetworkAdapter", TruncateIP(ip, 64),
+                       64, ADAPTER_TYPE_UNKNOWN, &field_trials);
+
+  // When there is no address added, it should return an unspecified
+  // address.
+  EXPECT_EQ(ipv6_network.GetBestIP(), IPAddress());
+  EXPECT_TRUE(IPIsUnspec(ipv6_network.GetBestIP()));
+
+  // Deprecated one should not be returned.
+  ipv6_network.AddIP(ip);
+  EXPECT_EQ(ipv6_network.GetBestIP(), IPAddress());
+
+  // Add ULA one. ULA is unique local address which is starting either
+  // with 0xfc or 0xfd.
+  ipstr = "fd00:fa00:4:1000:be30:5bff:fee5:c4";
+  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &ip));
+  ipv6_network.AddIP(ip);
+  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
+
+  // Add link local one.
+  ipstr = "fe80::aabb:ccff:fedd:eeff";
+  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &link_local));
+  ipv6_network.AddIP(link_local);
+  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(link_local));
+
+  // Add global one.
+  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c5";
+  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &ip));
+  ipv6_network.AddIP(ip);
+  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
+
+  // Add another link local address, then the compatible address is still global
+  // one.
+  ipstr = "fe80::aabb:ccff:fedd:eedd";
+  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &link_local));
+  ipv6_network.AddIP(link_local);
+  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
+
+  // Add global dynamic temporary one.
+  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c6";
+  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_TEMPORARY, &ip));
+  ipv6_network.AddIP(ip);
+  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
+
+  // Add another link local address, then the compatible address is still global
+  // dynamic one.
+  ipstr = "fe80::aabb:ccff:fedd:eedd";
+  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &link_local));
+  ipv6_network.AddIP(link_local);
+  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
+}
+
 TEST_F(NetworkTest, TestNetworkMonitoring) {
   FakeNetworkMonitorFactory factory;
   PhysicalSocketServer socket_server;