Index: webrtc/base/network.cc |
diff --git a/webrtc/base/network.cc b/webrtc/base/network.cc |
index 001877947046e2d7f5bcdd06c7b08a8ed75d9345..c9ad181776507b063e8e3f87aa5ca927c1f5ef8c 100644 |
--- a/webrtc/base/network.cc |
+++ b/webrtc/base/network.cc |
@@ -357,12 +357,34 @@ bool NetworkManagerBase::GetDefaultLocalAddress(int family, |
*ipaddr = default_local_ipv4_address_; |
return true; |
} else if (family == AF_INET6 && !default_local_ipv6_address_.IsNil()) { |
- *ipaddr = default_local_ipv6_address_; |
+ Network* ipv6_network = GetNetworkFromAddress(default_local_ipv6_address_); |
+ if (ipv6_network) { |
+ // If the default ipv6 network's BestIP is different than |
+ // default_local_ipv6_address_, use it instead. |
+ // This is to prevent potential IP address leakage. See WebRTC bug 5376. |
+ *ipaddr = ipv6_network->GetBestIP(); |
+ } else { |
+ *ipaddr = default_local_ipv6_address_; |
+ } |
return true; |
} |
return false; |
} |
+Network* NetworkManagerBase::GetNetworkFromAddress( |
+ const rtc::IPAddress& ip) const { |
+ for (Network* network : networks_) { |
+ const auto& ips = network->GetIPs(); |
+ if (std::find_if(ips.begin(), ips.end(), |
+ [ip](const InterfaceAddress& existing_ip) { |
+ return ip == static_cast<rtc::IPAddress>(existing_ip); |
+ }) != ips.end()) { |
+ return network; |
+ } |
+ } |
+ return nullptr; |
+} |
+ |
BasicNetworkManager::BasicNetworkManager() |
: thread_(NULL), sent_first_update_(false), start_count_(0), |
ignore_non_default_routes_(false) { |