Do not use deprecated IPv6 on Windows, and set temporary address attribute for IPv6
Currently webrtc does not have info about interface flags, thus it can use deprecated IPv6 and does not prefer temporary addresses as mentioned in https://www.rfc-editor.org/rfc/rfc8835#name-usage-of-temporary-ipv6-add
Test: not able to test it because cannot mock GetAdaptersAddresses system call on Windows. However, it should be correct because the implementation is the same as chromium code. https://source.chromium.org/chromium/chromium/src/+/main:net/base/network_interfaces_win.cc;l=182
Bug: webrtc:14334
Change-Id: Iae696b00368ae2f9480b542d2ddbc036338081f1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/300965
Commit-Queue: Diep Bui <diepbp@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39839}
diff --git a/rtc_base/network.cc b/rtc_base/network.cc
index 602ce17..3aecc00 100644
--- a/rtc_base/network.cc
+++ b/rtc_base/network.cc
@@ -201,6 +201,22 @@
return false;
}
+#if defined(WEBRTC_WIN)
+bool IpAddressAttributesEnabled(const webrtc::FieldTrialsView* field_trials) {
+ // Field trial key reserved in bugs.webrtc.org/14334
+ if (field_trials &&
+ field_trials->IsEnabled("WebRTC-IPv6NetworkResolutionFixes")) {
+ webrtc::FieldTrialParameter<bool> ip_address_attributes_enabled(
+ "IpAddressAttributesEnabled", false);
+ webrtc::ParseFieldTrial(
+ {&ip_address_attributes_enabled},
+ field_trials->Lookup("WebRTC-IPv6NetworkResolutionFixes"));
+ return ip_address_attributes_enabled;
+ }
+ return false;
+}
+#endif // WEBRTC_WIN
+
} // namespace
// These addresses are used as the targets to find out the default local address
@@ -548,6 +564,7 @@
SocketFactory* socket_factory,
const webrtc::FieldTrialsView* field_trials_view)
: NetworkManagerBase(field_trials_view),
+ field_trials_(field_trials_view),
network_monitor_factory_(network_monitor_factory),
socket_factory_(socket_factory),
allow_mac_based_ipv6_(
@@ -815,12 +832,27 @@
sockaddr_in6* v6_addr =
reinterpret_cast<sockaddr_in6*>(address->Address.lpSockaddr);
scope_id = v6_addr->sin6_scope_id;
- ip = IPAddress(v6_addr->sin6_addr);
- if (IsIgnoredIPv6(allow_mac_based_ipv6_, InterfaceAddress(ip))) {
+ // From http://technet.microsoft.com/en-us/ff568768(v=vs.60).aspx,
+ // the way to identify a temporary IPv6 Address is to check if
+ // PrefixOrigin is equal to IpPrefixOriginRouterAdvertisement and
+ // SuffixOrigin equal to IpSuffixOriginRandom.
+ int ip_address_attributes = IPV6_ADDRESS_FLAG_NONE;
+ if (IpAddressAttributesEnabled(field_trials_.get())) {
+ if (address->PrefixOrigin == IpPrefixOriginRouterAdvertisement &&
+ address->SuffixOrigin == IpSuffixOriginRandom) {
+ ip_address_attributes |= IPV6_ADDRESS_FLAG_TEMPORARY;
+ }
+ if (address->PreferredLifetime == 0) {
+ ip_address_attributes |= IPV6_ADDRESS_FLAG_DEPRECATED;
+ }
+ }
+ if (IsIgnoredIPv6(allow_mac_based_ipv6_,
+ InterfaceAddress(v6_addr->sin6_addr,
+ ip_address_attributes))) {
continue;
}
-
+ ip = InterfaceAddress(v6_addr->sin6_addr, ip_address_attributes);
break;
}
default: {
diff --git a/rtc_base/network.h b/rtc_base/network.h
index c7d73bf..5d84d67 100644
--- a/rtc_base/network.h
+++ b/rtc_base/network.h
@@ -361,6 +361,9 @@
bool sent_first_update_ = true;
int start_count_ = 0;
+ webrtc::AlwaysValidPointer<const webrtc::FieldTrialsView,
+ webrtc::FieldTrialBasedConfig>
+ field_trials_;
std::vector<std::string> network_ignore_list_;
NetworkMonitorFactory* const network_monitor_factory_;
SocketFactory* const socket_factory_;