1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "rtc_base/network.h"
12 
13 #if defined(WEBRTC_POSIX)
14 #include <net/if.h>
15 #endif  // WEBRTC_POSIX
16 
17 #if defined(WEBRTC_WIN)
18 #include <iphlpapi.h>
19 
20 #include "rtc_base/win32.h"
21 #elif !defined(__native_client__)
22 #include "rtc_base/ifaddrs_converter.h"
23 #endif
24 
25 #include <memory>
26 
27 #include "absl/algorithm/container.h"
28 #include "absl/strings/match.h"
29 #include "absl/strings/string_view.h"
30 #include "rtc_base/checks.h"
31 #include "rtc_base/logging.h"
32 #include "rtc_base/network_monitor.h"
33 #include "rtc_base/socket.h"  // includes something that makes windows happy
34 #include "rtc_base/string_encode.h"
35 #include "rtc_base/string_utils.h"
36 #include "rtc_base/strings/string_builder.h"
37 #include "rtc_base/thread.h"
38 
39 namespace rtc {
40 namespace {
41 
42 const uint32_t kUpdateNetworksMessage = 1;
43 const uint32_t kSignalNetworksMessage = 2;
44 
45 // Fetch list of networks every two seconds.
46 const int kNetworksUpdateIntervalMs = 2000;
47 
48 const int kHighestNetworkPreference = 127;
49 
50 typedef struct {
51   Network* net;
52   std::vector<InterfaceAddress> ips;
53 } AddressList;
54 
CompareNetworks(const Network * a,const Network * b)55 bool CompareNetworks(const Network* a, const Network* b) {
56   if (a->prefix_length() == b->prefix_length()) {
57     if (a->name() == b->name()) {
58       return a->prefix() < b->prefix();
59     }
60   }
61   return a->name() < b->name();
62 }
63 
SortNetworks(const Network * a,const Network * b)64 bool SortNetworks(const Network* a, const Network* b) {
65   // Network types will be preferred above everything else while sorting
66   // Networks.
67 
68   // Networks are sorted first by type.
69   if (a->type() != b->type()) {
70     return a->type() < b->type();
71   }
72 
73   IPAddress ip_a = a->GetBestIP();
74   IPAddress ip_b = b->GetBestIP();
75 
76   // After type, networks are sorted by IP address precedence values
77   // from RFC 3484-bis
78   if (IPAddressPrecedence(ip_a) != IPAddressPrecedence(ip_b)) {
79     return IPAddressPrecedence(ip_a) > IPAddressPrecedence(ip_b);
80   }
81 
82   // TODO(mallinath) - Add VPN and Link speed conditions while sorting.
83 
84   // Networks are sorted last by key.
85   return a->key() < b->key();
86 }
87 
ComputeNetworkCostByType(int type)88 uint16_t ComputeNetworkCostByType(int type) {
89   // TODO(jonaso) : Rollout support for cellular network cost using A/B
90   // experiment to make sure it does not introduce regressions.
91   switch (type) {
92     case rtc::ADAPTER_TYPE_ETHERNET:
93     case rtc::ADAPTER_TYPE_LOOPBACK:
94       return kNetworkCostMin;
95     case rtc::ADAPTER_TYPE_WIFI:
96       return kNetworkCostLow;
97     case rtc::ADAPTER_TYPE_CELLULAR:
98     case rtc::ADAPTER_TYPE_CELLULAR_2G:
99     case rtc::ADAPTER_TYPE_CELLULAR_3G:
100     case rtc::ADAPTER_TYPE_CELLULAR_4G:
101     case rtc::ADAPTER_TYPE_CELLULAR_5G:
102       return kNetworkCostCellular;
103     case rtc::ADAPTER_TYPE_ANY:
104       // Candidates gathered from the any-address/wildcard ports, as backups,
105       // are given the maximum cost so that if there are other candidates with
106       // known interface types, we would not select candidate pairs using these
107       // backup candidates if other selection criteria with higher precedence
108       // (network conditions over the route) are the same. Note that setting the
109       // cost to kNetworkCostUnknown would be problematic since
110       // ADAPTER_TYPE_CELLULAR would then have a higher cost. See
111       // P2PTransportChannel::SortConnectionsAndUpdateState for how we rank and
112       // select candidate pairs, where the network cost is among the criteria.
113       return kNetworkCostMax;
114     case rtc::ADAPTER_TYPE_VPN:
115       // The cost of a VPN should be computed using its underlying network type.
116       RTC_NOTREACHED();
117       return kNetworkCostUnknown;
118     default:
119       return kNetworkCostUnknown;
120   }
121 }
122 
123 #if !defined(__native_client__)
IsIgnoredIPv6(const InterfaceAddress & ip)124 bool IsIgnoredIPv6(const InterfaceAddress& ip) {
125   if (ip.family() != AF_INET6) {
126     return false;
127   }
128 
129   // Link-local addresses require scope id to be bound successfully.
130   // However, our IPAddress structure doesn't carry that so the
131   // information is lost and causes binding failure.
132   if (IPIsLinkLocal(ip)) {
133     return true;
134   }
135 
136   // Any MAC based IPv6 should be avoided to prevent the MAC tracking.
137   if (IPIsMacBased(ip)) {
138     return true;
139   }
140 
141   // Ignore deprecated IPv6.
142   if (ip.ipv6_flags() & IPV6_ADDRESS_FLAG_DEPRECATED) {
143     return true;
144   }
145 
146   return false;
147 }
148 #endif  // !defined(__native_client__)
149 
150 }  // namespace
151 
152 // These addresses are used as the targets to find out the default local address
153 // on a multi-homed endpoint. They are actually DNS servers.
154 const char kPublicIPv4Host[] = "8.8.8.8";
155 const char kPublicIPv6Host[] = "2001:4860:4860::8888";
156 const int kPublicPort = 53;  // DNS port.
157 
MakeNetworkKey(const std::string & name,const IPAddress & prefix,int prefix_length)158 std::string MakeNetworkKey(const std::string& name,
159                            const IPAddress& prefix,
160                            int prefix_length) {
161   rtc::StringBuilder ost;
162   ost << name << "%" << prefix.ToString() << "/" << prefix_length;
163   return ost.Release();
164 }
165 // Test if the network name matches the type<number> pattern, e.g. eth0. The
166 // matching is case-sensitive.
MatchTypeNameWithIndexPattern(absl::string_view network_name,absl::string_view type_name)167 bool MatchTypeNameWithIndexPattern(absl::string_view network_name,
168                                    absl::string_view type_name) {
169   if (!absl::StartsWith(network_name, type_name)) {
170     return false;
171   }
172   return absl::c_none_of(network_name.substr(type_name.size()),
173                          [](char c) { return !isdigit(c); });
174 }
175 
176 // A cautious note that this method may not provide an accurate adapter type
177 // based on the string matching. Incorrect type of adapters can affect the
178 // result of the downstream network filtering, see e.g.
179 // BasicPortAllocatorSession::GetNetworks when
180 // PORTALLOCATOR_DISABLE_COSTLY_NETWORKS is turned on.
GetAdapterTypeFromName(const char * network_name)181 AdapterType GetAdapterTypeFromName(const char* network_name) {
182   if (MatchTypeNameWithIndexPattern(network_name, "lo")) {
183     // Note that we have a more robust way to determine if a network interface
184     // is a loopback interface by checking the flag IFF_LOOPBACK in ifa_flags of
185     // an ifaddr struct. See ConvertIfAddrs in this file.
186     return ADAPTER_TYPE_LOOPBACK;
187   }
188 
189   if (MatchTypeNameWithIndexPattern(network_name, "eth")) {
190     return ADAPTER_TYPE_ETHERNET;
191   }
192 
193   if (MatchTypeNameWithIndexPattern(network_name, "wlan")) {
194     return ADAPTER_TYPE_WIFI;
195   }
196 
197   if (MatchTypeNameWithIndexPattern(network_name, "ipsec") ||
198       MatchTypeNameWithIndexPattern(network_name, "tun") ||
199       MatchTypeNameWithIndexPattern(network_name, "utun") ||
200       MatchTypeNameWithIndexPattern(network_name, "tap")) {
201     return ADAPTER_TYPE_VPN;
202   }
203 #if defined(WEBRTC_IOS)
204   // Cell networks are pdp_ipN on iOS.
205   if (MatchTypeNameWithIndexPattern(network_name, "pdp_ip")) {
206     return ADAPTER_TYPE_CELLULAR;
207   }
208   if (MatchTypeNameWithIndexPattern(network_name, "en")) {
209     // This may not be most accurate because sometimes Ethernet interface
210     // name also starts with "en" but it is better than showing it as
211     // "unknown" type.
212     // TODO(honghaiz): Write a proper IOS network manager.
213     return ADAPTER_TYPE_WIFI;
214   }
215 #elif defined(WEBRTC_ANDROID)
216   if (MatchTypeNameWithIndexPattern(network_name, "rmnet") ||
217       MatchTypeNameWithIndexPattern(network_name, "rmnet_data") ||
218       MatchTypeNameWithIndexPattern(network_name, "v4-rmnet") ||
219       MatchTypeNameWithIndexPattern(network_name, "v4-rmnet_data") ||
220       MatchTypeNameWithIndexPattern(network_name, "clat")) {
221     return ADAPTER_TYPE_CELLULAR;
222   }
223 #endif
224 
225 #if defined(WEBRTC_BSD)
226   // Treat all other network interface names as ethernet on BSD
227   return ADAPTER_TYPE_ETHERNET;
228 #else
229   return ADAPTER_TYPE_UNKNOWN;
230 #endif
231 }
232 
NetworkManager()233 NetworkManager::NetworkManager() {}
234 
~NetworkManager()235 NetworkManager::~NetworkManager() {}
236 
enumeration_permission() const237 NetworkManager::EnumerationPermission NetworkManager::enumeration_permission()
238     const {
239   return ENUMERATION_ALLOWED;
240 }
241 
GetDefaultLocalAddress(int family,IPAddress * addr) const242 bool NetworkManager::GetDefaultLocalAddress(int family, IPAddress* addr) const {
243   return false;
244 }
245 
GetMdnsResponder() const246 webrtc::MdnsResponderInterface* NetworkManager::GetMdnsResponder() const {
247   return nullptr;
248 }
249 
NetworkManagerBase()250 NetworkManagerBase::NetworkManagerBase()
251     : enumeration_permission_(NetworkManager::ENUMERATION_ALLOWED) {}
252 
~NetworkManagerBase()253 NetworkManagerBase::~NetworkManagerBase() {
254   for (const auto& kv : networks_map_) {
255     delete kv.second;
256   }
257 }
258 
259 NetworkManager::EnumerationPermission
enumeration_permission() const260 NetworkManagerBase::enumeration_permission() const {
261   return enumeration_permission_;
262 }
263 
GetAnyAddressNetworks(NetworkList * networks)264 void NetworkManagerBase::GetAnyAddressNetworks(NetworkList* networks) {
265   if (!ipv4_any_address_network_) {
266     const rtc::IPAddress ipv4_any_address(INADDR_ANY);
267     ipv4_any_address_network_.reset(
268         new rtc::Network("any", "any", ipv4_any_address, 0, ADAPTER_TYPE_ANY));
269     ipv4_any_address_network_->set_default_local_address_provider(this);
270     ipv4_any_address_network_->set_mdns_responder_provider(this);
271     ipv4_any_address_network_->AddIP(ipv4_any_address);
272   }
273   networks->push_back(ipv4_any_address_network_.get());
274 
275   if (!ipv6_any_address_network_) {
276     const rtc::IPAddress ipv6_any_address(in6addr_any);
277     ipv6_any_address_network_.reset(
278         new rtc::Network("any", "any", ipv6_any_address, 0, ADAPTER_TYPE_ANY));
279     ipv6_any_address_network_->set_default_local_address_provider(this);
280     ipv6_any_address_network_->set_mdns_responder_provider(this);
281     ipv6_any_address_network_->AddIP(ipv6_any_address);
282   }
283   networks->push_back(ipv6_any_address_network_.get());
284 }
285 
GetNetworks(NetworkList * result) const286 void NetworkManagerBase::GetNetworks(NetworkList* result) const {
287   result->clear();
288   result->insert(result->begin(), networks_.begin(), networks_.end());
289 }
290 
MergeNetworkList(const NetworkList & new_networks,bool * changed)291 void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
292                                           bool* changed) {
293   NetworkManager::Stats stats;
294   MergeNetworkList(new_networks, changed, &stats);
295 }
296 
MergeNetworkList(const NetworkList & new_networks,bool * changed,NetworkManager::Stats * stats)297 void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
298                                           bool* changed,
299                                           NetworkManager::Stats* stats) {
300   *changed = false;
301   // AddressList in this map will track IP addresses for all Networks
302   // with the same key.
303   std::map<std::string, AddressList> consolidated_address_list;
304   NetworkList list(new_networks);
305   absl::c_sort(list, CompareNetworks);
306   // First, build a set of network-keys to the ipaddresses.
307   for (Network* network : list) {
308     bool might_add_to_merged_list = false;
309     std::string key = MakeNetworkKey(network->name(), network->prefix(),
310                                      network->prefix_length());
311     if (consolidated_address_list.find(key) ==
312         consolidated_address_list.end()) {
313       AddressList addrlist;
314       addrlist.net = network;
315       consolidated_address_list[key] = addrlist;
316       might_add_to_merged_list = true;
317     }
318     const std::vector<InterfaceAddress>& addresses = network->GetIPs();
319     AddressList& current_list = consolidated_address_list[key];
320     for (const InterfaceAddress& address : addresses) {
321       current_list.ips.push_back(address);
322     }
323     if (!might_add_to_merged_list) {
324       delete network;
325     } else {
326       if (current_list.ips[0].family() == AF_INET) {
327         stats->ipv4_network_count++;
328       } else {
329         RTC_DCHECK(current_list.ips[0].family() == AF_INET6);
330         stats->ipv6_network_count++;
331       }
332     }
333   }
334 
335   // Next, look for existing network objects to re-use.
336   // Result of Network merge. Element in this list should have unique key.
337   NetworkList merged_list;
338   for (const auto& kv : consolidated_address_list) {
339     const std::string& key = kv.first;
340     Network* net = kv.second.net;
341     auto existing = networks_map_.find(key);
342     if (existing == networks_map_.end()) {
343       // This network is new. Place it in the network map.
344       merged_list.push_back(net);
345       networks_map_[key] = net;
346       net->set_id(next_available_network_id_++);
347       // Also, we might have accumulated IPAddresses from the first
348       // step, set it here.
349       net->SetIPs(kv.second.ips, true);
350       *changed = true;
351     } else {
352       // This network exists in the map already. Reset its IP addresses.
353       Network* existing_net = existing->second;
354       *changed = existing_net->SetIPs(kv.second.ips, *changed);
355       merged_list.push_back(existing_net);
356       if (net->type() != ADAPTER_TYPE_UNKNOWN &&
357           net->type() != existing_net->type()) {
358         existing_net->set_type(net->type());
359         *changed = true;
360       }
361       // If the existing network was not active, networks have changed.
362       if (!existing_net->active()) {
363         *changed = true;
364       }
365       RTC_DCHECK(net->active());
366       if (existing_net != net) {
367         delete net;
368       }
369     }
370     networks_map_[key]->set_mdns_responder_provider(this);
371   }
372   // It may still happen that the merged list is a subset of |networks_|.
373   // To detect this change, we compare their sizes.
374   if (merged_list.size() != networks_.size()) {
375     *changed = true;
376   }
377 
378   // If the network list changes, we re-assign |networks_| to the merged list
379   // and re-sort it.
380   if (*changed) {
381     networks_ = merged_list;
382     // Reset the active states of all networks.
383     for (const auto& kv : networks_map_) {
384       Network* network = kv.second;
385       // If |network| is in the newly generated |networks_|, it is active.
386       bool found = absl::c_linear_search(networks_, network);
387       network->set_active(found);
388     }
389     absl::c_sort(networks_, SortNetworks);
390     // Now network interfaces are sorted, we should set the preference value
391     // for each of the interfaces we are planning to use.
392     // Preference order of network interfaces might have changed from previous
393     // sorting due to addition of higher preference network interface.
394     // Since we have already sorted the network interfaces based on our
395     // requirements, we will just assign a preference value starting with 127,
396     // in decreasing order.
397     int pref = kHighestNetworkPreference;
398     for (Network* network : networks_) {
399       network->set_preference(pref);
400       if (pref > 0) {
401         --pref;
402       } else {
403         RTC_LOG(LS_ERROR) << "Too many network interfaces to handle!";
404         break;
405       }
406     }
407   }
408 }
409 
set_default_local_addresses(const IPAddress & ipv4,const IPAddress & ipv6)410 void NetworkManagerBase::set_default_local_addresses(const IPAddress& ipv4,
411                                                      const IPAddress& ipv6) {
412   if (ipv4.family() == AF_INET) {
413     default_local_ipv4_address_ = ipv4;
414   }
415   if (ipv6.family() == AF_INET6) {
416     default_local_ipv6_address_ = ipv6;
417   }
418 }
419 
GetDefaultLocalAddress(int family,IPAddress * ipaddr) const420 bool NetworkManagerBase::GetDefaultLocalAddress(int family,
421                                                 IPAddress* ipaddr) const {
422   if (family == AF_INET && !default_local_ipv4_address_.IsNil()) {
423     *ipaddr = default_local_ipv4_address_;
424     return true;
425   } else if (family == AF_INET6 && !default_local_ipv6_address_.IsNil()) {
426     Network* ipv6_network = GetNetworkFromAddress(default_local_ipv6_address_);
427     if (ipv6_network) {
428       // If the default ipv6 network's BestIP is different than
429       // default_local_ipv6_address_, use it instead.
430       // This is to prevent potential IP address leakage. See WebRTC bug 5376.
431       *ipaddr = ipv6_network->GetBestIP();
432     } else {
433       *ipaddr = default_local_ipv6_address_;
434     }
435     return true;
436   }
437   return false;
438 }
439 
GetNetworkFromAddress(const rtc::IPAddress & ip) const440 Network* NetworkManagerBase::GetNetworkFromAddress(
441     const rtc::IPAddress& ip) const {
442   for (Network* network : networks_) {
443     const auto& ips = network->GetIPs();
444     if (absl::c_any_of(ips, [&](const InterfaceAddress& existing_ip) {
445           return ip == static_cast<rtc::IPAddress>(existing_ip);
446         })) {
447       return network;
448     }
449   }
450   return nullptr;
451 }
452 
BasicNetworkManager()453 BasicNetworkManager::BasicNetworkManager()
454     : thread_(nullptr), sent_first_update_(false), start_count_(0) {}
455 
~BasicNetworkManager()456 BasicNetworkManager::~BasicNetworkManager() {}
457 
OnNetworksChanged()458 void BasicNetworkManager::OnNetworksChanged() {
459   RTC_LOG(LS_INFO) << "Network change was observed";
460   UpdateNetworksOnce();
461 }
462 
463 #if defined(__native_client__)
464 
CreateNetworks(bool include_ignored,NetworkList * networks) const465 bool BasicNetworkManager::CreateNetworks(bool include_ignored,
466                                          NetworkList* networks) const {
467   RTC_NOTREACHED();
468   RTC_LOG(LS_WARNING) << "BasicNetworkManager doesn't work on NaCl yet";
469   return false;
470 }
471 
472 #elif defined(WEBRTC_POSIX)
ConvertIfAddrs(struct ifaddrs * interfaces,IfAddrsConverter * ifaddrs_converter,bool include_ignored,NetworkList * networks) const473 void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
474                                          IfAddrsConverter* ifaddrs_converter,
475                                          bool include_ignored,
476                                          NetworkList* networks) const {
477   NetworkMap current_networks;
478 
479   for (struct ifaddrs* cursor = interfaces; cursor != nullptr;
480        cursor = cursor->ifa_next) {
481     IPAddress prefix;
482     IPAddress mask;
483     InterfaceAddress ip;
484     int scope_id = 0;
485 
486     // Some interfaces may not have address assigned.
487     if (!cursor->ifa_addr || !cursor->ifa_netmask) {
488       continue;
489     }
490     // Skip ones which are down.
491     if (!(cursor->ifa_flags & IFF_RUNNING)) {
492       continue;
493     }
494     // Skip unknown family.
495     if (cursor->ifa_addr->sa_family != AF_INET &&
496         cursor->ifa_addr->sa_family != AF_INET6) {
497       continue;
498     }
499     // Convert to InterfaceAddress.
500     if (!ifaddrs_converter->ConvertIfAddrsToIPAddress(cursor, &ip, &mask)) {
501       continue;
502     }
503 
504     // Special case for IPv6 address.
505     if (cursor->ifa_addr->sa_family == AF_INET6) {
506       if (IsIgnoredIPv6(ip)) {
507         continue;
508       }
509       scope_id =
510           reinterpret_cast<sockaddr_in6*>(cursor->ifa_addr)->sin6_scope_id;
511     }
512 
513     AdapterType adapter_type = ADAPTER_TYPE_UNKNOWN;
514     AdapterType vpn_underlying_adapter_type = ADAPTER_TYPE_UNKNOWN;
515     if (cursor->ifa_flags & IFF_LOOPBACK) {
516       adapter_type = ADAPTER_TYPE_LOOPBACK;
517     } else {
518       // If there is a network_monitor, use it to get the adapter type.
519       // Otherwise, get the adapter type based on a few name matching rules.
520       if (network_monitor_) {
521         adapter_type = network_monitor_->GetAdapterType(cursor->ifa_name);
522       }
523       if (adapter_type == ADAPTER_TYPE_UNKNOWN) {
524         adapter_type = GetAdapterTypeFromName(cursor->ifa_name);
525       }
526     }
527 
528     if (adapter_type == ADAPTER_TYPE_VPN && network_monitor_) {
529       vpn_underlying_adapter_type =
530           network_monitor_->GetVpnUnderlyingAdapterType(cursor->ifa_name);
531     }
532     int prefix_length = CountIPMaskBits(mask);
533     prefix = TruncateIP(ip, prefix_length);
534     std::string key =
535         MakeNetworkKey(std::string(cursor->ifa_name), prefix, prefix_length);
536     auto iter = current_networks.find(key);
537     if (iter == current_networks.end()) {
538       // TODO(phoglund): Need to recognize other types as well.
539       std::unique_ptr<Network> network(
540           new Network(cursor->ifa_name, cursor->ifa_name, prefix, prefix_length,
541                       adapter_type));
542       network->set_default_local_address_provider(this);
543       network->set_scope_id(scope_id);
544       network->AddIP(ip);
545       network->set_ignored(IsIgnoredNetwork(*network));
546       network->set_underlying_type_for_vpn(vpn_underlying_adapter_type);
547       if (include_ignored || !network->ignored()) {
548         current_networks[key] = network.get();
549         networks->push_back(network.release());
550       }
551     } else {
552       Network* existing_network = iter->second;
553       existing_network->AddIP(ip);
554       if (adapter_type != ADAPTER_TYPE_UNKNOWN) {
555         existing_network->set_type(adapter_type);
556         existing_network->set_underlying_type_for_vpn(
557             vpn_underlying_adapter_type);
558       }
559     }
560   }
561 }
562 
CreateNetworks(bool include_ignored,NetworkList * networks) const563 bool BasicNetworkManager::CreateNetworks(bool include_ignored,
564                                          NetworkList* networks) const {
565   struct ifaddrs* interfaces;
566   int error = getifaddrs(&interfaces);
567   if (error != 0) {
568     RTC_LOG_ERR(LERROR) << "getifaddrs failed to gather interface data: "
569                         << error;
570     return false;
571   }
572 
573   std::unique_ptr<IfAddrsConverter> ifaddrs_converter(CreateIfAddrsConverter());
574   ConvertIfAddrs(interfaces, ifaddrs_converter.get(), include_ignored,
575                  networks);
576 
577   freeifaddrs(interfaces);
578   return true;
579 }
580 
581 #elif defined(WEBRTC_WIN)
582 
GetPrefix(PIP_ADAPTER_PREFIX prefixlist,const IPAddress & ip,IPAddress * prefix)583 unsigned int GetPrefix(PIP_ADAPTER_PREFIX prefixlist,
584                        const IPAddress& ip,
585                        IPAddress* prefix) {
586   IPAddress current_prefix;
587   IPAddress best_prefix;
588   unsigned int best_length = 0;
589   while (prefixlist) {
590     // Look for the longest matching prefix in the prefixlist.
591     if (prefixlist->Address.lpSockaddr == nullptr ||
592         prefixlist->Address.lpSockaddr->sa_family != ip.family()) {
593       prefixlist = prefixlist->Next;
594       continue;
595     }
596     switch (prefixlist->Address.lpSockaddr->sa_family) {
597       case AF_INET: {
598         sockaddr_in* v4_addr =
599             reinterpret_cast<sockaddr_in*>(prefixlist->Address.lpSockaddr);
600         current_prefix = IPAddress(v4_addr->sin_addr);
601         break;
602       }
603       case AF_INET6: {
604         sockaddr_in6* v6_addr =
605             reinterpret_cast<sockaddr_in6*>(prefixlist->Address.lpSockaddr);
606         current_prefix = IPAddress(v6_addr->sin6_addr);
607         break;
608       }
609       default: {
610         prefixlist = prefixlist->Next;
611         continue;
612       }
613     }
614     if (TruncateIP(ip, prefixlist->PrefixLength) == current_prefix &&
615         prefixlist->PrefixLength > best_length) {
616       best_prefix = current_prefix;
617       best_length = prefixlist->PrefixLength;
618     }
619     prefixlist = prefixlist->Next;
620   }
621   *prefix = best_prefix;
622   return best_length;
623 }
624 
CreateNetworks(bool include_ignored,NetworkList * networks) const625 bool BasicNetworkManager::CreateNetworks(bool include_ignored,
626                                          NetworkList* networks) const {
627   NetworkMap current_networks;
628   // MSDN recommends a 15KB buffer for the first try at GetAdaptersAddresses.
629   size_t buffer_size = 16384;
630   std::unique_ptr<char[]> adapter_info(new char[buffer_size]);
631   PIP_ADAPTER_ADDRESSES adapter_addrs =
632       reinterpret_cast<PIP_ADAPTER_ADDRESSES>(adapter_info.get());
633   int adapter_flags = (GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_ANYCAST |
634                        GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_INCLUDE_PREFIX);
635   int ret = 0;
636   do {
637     adapter_info.reset(new char[buffer_size]);
638     adapter_addrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(adapter_info.get());
639     ret = GetAdaptersAddresses(AF_UNSPEC, adapter_flags, 0, adapter_addrs,
640                                reinterpret_cast<PULONG>(&buffer_size));
641   } while (ret == ERROR_BUFFER_OVERFLOW);
642   if (ret != ERROR_SUCCESS) {
643     return false;
644   }
645   int count = 0;
646   while (adapter_addrs) {
647     if (adapter_addrs->OperStatus == IfOperStatusUp) {
648       PIP_ADAPTER_UNICAST_ADDRESS address = adapter_addrs->FirstUnicastAddress;
649       PIP_ADAPTER_PREFIX prefixlist = adapter_addrs->FirstPrefix;
650       std::string name;
651       std::string description;
652 #if !defined(NDEBUG)
653       name = ToUtf8(adapter_addrs->FriendlyName,
654                     wcslen(adapter_addrs->FriendlyName));
655 #endif
656       description = ToUtf8(adapter_addrs->Description,
657                            wcslen(adapter_addrs->Description));
658       for (; address; address = address->Next) {
659 #if defined(NDEBUG)
660         name = rtc::ToString(count);
661 #endif
662 
663         IPAddress ip;
664         int scope_id = 0;
665         std::unique_ptr<Network> network;
666         switch (address->Address.lpSockaddr->sa_family) {
667           case AF_INET: {
668             sockaddr_in* v4_addr =
669                 reinterpret_cast<sockaddr_in*>(address->Address.lpSockaddr);
670             ip = IPAddress(v4_addr->sin_addr);
671             break;
672           }
673           case AF_INET6: {
674             sockaddr_in6* v6_addr =
675                 reinterpret_cast<sockaddr_in6*>(address->Address.lpSockaddr);
676             scope_id = v6_addr->sin6_scope_id;
677             ip = IPAddress(v6_addr->sin6_addr);
678 
679             if (IsIgnoredIPv6(InterfaceAddress(ip))) {
680               continue;
681             }
682 
683             break;
684           }
685           default: {
686             continue;
687           }
688         }
689 
690         IPAddress prefix;
691         int prefix_length = GetPrefix(prefixlist, ip, &prefix);
692         std::string key = MakeNetworkKey(name, prefix, prefix_length);
693         auto existing_network = current_networks.find(key);
694         if (existing_network == current_networks.end()) {
695           AdapterType adapter_type = ADAPTER_TYPE_UNKNOWN;
696           switch (adapter_addrs->IfType) {
697             case IF_TYPE_SOFTWARE_LOOPBACK:
698               adapter_type = ADAPTER_TYPE_LOOPBACK;
699               break;
700             case IF_TYPE_ETHERNET_CSMACD:
701             case IF_TYPE_ETHERNET_3MBIT:
702             case IF_TYPE_IEEE80212:
703             case IF_TYPE_FASTETHER:
704             case IF_TYPE_FASTETHER_FX:
705             case IF_TYPE_GIGABITETHERNET:
706               adapter_type = ADAPTER_TYPE_ETHERNET;
707               break;
708             case IF_TYPE_IEEE80211:
709               adapter_type = ADAPTER_TYPE_WIFI;
710               break;
711             case IF_TYPE_WWANPP:
712             case IF_TYPE_WWANPP2:
713               adapter_type = ADAPTER_TYPE_CELLULAR;
714               break;
715             default:
716               // TODO(phoglund): Need to recognize other types as well.
717               adapter_type = ADAPTER_TYPE_UNKNOWN;
718               break;
719           }
720           std::unique_ptr<Network> network(new Network(
721               name, description, prefix, prefix_length, adapter_type));
722           network->set_default_local_address_provider(this);
723           network->set_mdns_responder_provider(this);
724           network->set_scope_id(scope_id);
725           network->AddIP(ip);
726           bool ignored = IsIgnoredNetwork(*network);
727           network->set_ignored(ignored);
728           if (include_ignored || !network->ignored()) {
729             current_networks[key] = network.get();
730             networks->push_back(network.release());
731           }
732         } else {
733           (*existing_network).second->AddIP(ip);
734         }
735       }
736       // Count is per-adapter - all 'Networks' created from the same
737       // adapter need to have the same name.
738       ++count;
739     }
740     adapter_addrs = adapter_addrs->Next;
741   }
742   return true;
743 }
744 #endif  // WEBRTC_WIN
745 
IsIgnoredNetwork(const Network & network) const746 bool BasicNetworkManager::IsIgnoredNetwork(const Network& network) const {
747   // Ignore networks on the explicit ignore list.
748   for (const std::string& ignored_name : network_ignore_list_) {
749     if (network.name() == ignored_name) {
750       return true;
751     }
752   }
753 
754 #if defined(WEBRTC_POSIX)
755   // Filter out VMware/VirtualBox interfaces, typically named vmnet1,
756   // vmnet8, or vboxnet0.
757   if (strncmp(network.name().c_str(), "vmnet", 5) == 0 ||
758       strncmp(network.name().c_str(), "vnic", 4) == 0 ||
759       strncmp(network.name().c_str(), "vboxnet", 7) == 0) {
760     return true;
761   }
762 #elif defined(WEBRTC_WIN)
763   // Ignore any HOST side vmware adapters with a description like:
764   // VMware Virtual Ethernet Adapter for VMnet1
765   // but don't ignore any GUEST side adapters with a description like:
766   // VMware Accelerated AMD PCNet Adapter #2
767   if (strstr(network.description().c_str(), "VMnet") != nullptr) {
768     return true;
769   }
770 #endif
771 
772   // Ignore any networks with a 0.x.y.z IP
773   if (network.prefix().family() == AF_INET) {
774     return (network.prefix().v4AddressAsHostOrderInteger() < 0x01000000);
775   }
776 
777   return false;
778 }
779 
StartUpdating()780 void BasicNetworkManager::StartUpdating() {
781   thread_ = Thread::Current();
782   if (start_count_) {
783     // If network interfaces are already discovered and signal is sent,
784     // we should trigger network signal immediately for the new clients
785     // to start allocating ports.
786     if (sent_first_update_)
787       thread_->Post(RTC_FROM_HERE, this, kSignalNetworksMessage);
788   } else {
789     thread_->Post(RTC_FROM_HERE, this, kUpdateNetworksMessage);
790     StartNetworkMonitor();
791   }
792   ++start_count_;
793 }
794 
StopUpdating()795 void BasicNetworkManager::StopUpdating() {
796   RTC_DCHECK(Thread::Current() == thread_);
797   if (!start_count_)
798     return;
799 
800   --start_count_;
801   if (!start_count_) {
802     thread_->Clear(this);
803     sent_first_update_ = false;
804     StopNetworkMonitor();
805   }
806 }
807 
StartNetworkMonitor()808 void BasicNetworkManager::StartNetworkMonitor() {
809   NetworkMonitorFactory* factory = NetworkMonitorFactory::GetFactory();
810   if (factory == nullptr) {
811     return;
812   }
813   if (!network_monitor_) {
814     network_monitor_.reset(factory->CreateNetworkMonitor());
815     if (!network_monitor_) {
816       return;
817     }
818     network_monitor_->SignalNetworksChanged.connect(
819         this, &BasicNetworkManager::OnNetworksChanged);
820   }
821   network_monitor_->Start();
822 }
823 
StopNetworkMonitor()824 void BasicNetworkManager::StopNetworkMonitor() {
825   if (!network_monitor_) {
826     return;
827   }
828   network_monitor_->Stop();
829 }
830 
OnMessage(Message * msg)831 void BasicNetworkManager::OnMessage(Message* msg) {
832   switch (msg->message_id) {
833     case kUpdateNetworksMessage: {
834       UpdateNetworksContinually();
835       break;
836     }
837     case kSignalNetworksMessage: {
838       SignalNetworksChanged();
839       break;
840     }
841     default:
842       RTC_NOTREACHED();
843   }
844 }
845 
QueryDefaultLocalAddress(int family) const846 IPAddress BasicNetworkManager::QueryDefaultLocalAddress(int family) const {
847   RTC_DCHECK(thread_ == Thread::Current());
848   RTC_DCHECK(thread_->socketserver() != nullptr);
849   RTC_DCHECK(family == AF_INET || family == AF_INET6);
850 
851   std::unique_ptr<AsyncSocket> socket(
852       thread_->socketserver()->CreateAsyncSocket(family, SOCK_DGRAM));
853   if (!socket) {
854     RTC_LOG_ERR(LERROR) << "Socket creation failed";
855     return IPAddress();
856   }
857 
858   if (socket->Connect(SocketAddress(
859           family == AF_INET ? kPublicIPv4Host : kPublicIPv6Host, kPublicPort)) <
860       0) {
861     if (socket->GetError() != ENETUNREACH &&
862         socket->GetError() != EHOSTUNREACH) {
863       // Ignore the expected case of "host/net unreachable" - which happens if
864       // the network is V4- or V6-only.
865       RTC_LOG(LS_INFO) << "Connect failed with " << socket->GetError();
866     }
867     return IPAddress();
868   }
869   return socket->GetLocalAddress().ipaddr();
870 }
871 
UpdateNetworksOnce()872 void BasicNetworkManager::UpdateNetworksOnce() {
873   if (!start_count_)
874     return;
875 
876   RTC_DCHECK(Thread::Current() == thread_);
877 
878   NetworkList list;
879   if (!CreateNetworks(false, &list)) {
880     SignalError();
881   } else {
882     bool changed;
883     NetworkManager::Stats stats;
884     MergeNetworkList(list, &changed, &stats);
885     set_default_local_addresses(QueryDefaultLocalAddress(AF_INET),
886                                 QueryDefaultLocalAddress(AF_INET6));
887     if (changed || !sent_first_update_) {
888       SignalNetworksChanged();
889       sent_first_update_ = true;
890     }
891   }
892 }
893 
UpdateNetworksContinually()894 void BasicNetworkManager::UpdateNetworksContinually() {
895   UpdateNetworksOnce();
896   thread_->PostDelayed(RTC_FROM_HERE, kNetworksUpdateIntervalMs, this,
897                        kUpdateNetworksMessage);
898 }
899 
DumpNetworks()900 void BasicNetworkManager::DumpNetworks() {
901   NetworkList list;
902   GetNetworks(&list);
903   RTC_LOG(LS_INFO) << "NetworkManager detected " << list.size() << " networks:";
904   for (const Network* network : list) {
905     RTC_LOG(LS_INFO) << network->ToString() << ": " << network->description()
906                      << ", active ? " << network->active()
907                      << ((network->ignored()) ? ", Ignored" : "");
908   }
909 }
910 
Network(const std::string & name,const std::string & desc,const IPAddress & prefix,int prefix_length)911 Network::Network(const std::string& name,
912                  const std::string& desc,
913                  const IPAddress& prefix,
914                  int prefix_length)
915     : name_(name),
916       description_(desc),
917       prefix_(prefix),
918       prefix_length_(prefix_length),
919       key_(MakeNetworkKey(name, prefix, prefix_length)),
920       scope_id_(0),
921       ignored_(false),
922       type_(ADAPTER_TYPE_UNKNOWN),
923       preference_(0) {}
924 
Network(const std::string & name,const std::string & desc,const IPAddress & prefix,int prefix_length,AdapterType type)925 Network::Network(const std::string& name,
926                  const std::string& desc,
927                  const IPAddress& prefix,
928                  int prefix_length,
929                  AdapterType type)
930     : name_(name),
931       description_(desc),
932       prefix_(prefix),
933       prefix_length_(prefix_length),
934       key_(MakeNetworkKey(name, prefix, prefix_length)),
935       scope_id_(0),
936       ignored_(false),
937       type_(type),
938       preference_(0) {}
939 
940 Network::Network(const Network&) = default;
941 
942 Network::~Network() = default;
943 
944 // Sets the addresses of this network. Returns true if the address set changed.
945 // Change detection is short circuited if the changed argument is true.
SetIPs(const std::vector<InterfaceAddress> & ips,bool changed)946 bool Network::SetIPs(const std::vector<InterfaceAddress>& ips, bool changed) {
947   // Detect changes with a nested loop; n-squared but we expect on the order
948   // of 2-3 addresses per network.
949   changed = changed || ips.size() != ips_.size();
950   if (!changed) {
951     for (const InterfaceAddress& ip : ips) {
952       if (!absl::c_linear_search(ips_, ip)) {
953         changed = true;
954         break;
955       }
956     }
957   }
958 
959   ips_ = ips;
960   return changed;
961 }
962 
963 // Select the best IP address to use from this Network.
GetBestIP() const964 IPAddress Network::GetBestIP() const {
965   if (ips_.size() == 0) {
966     return IPAddress();
967   }
968 
969   if (prefix_.family() == AF_INET) {
970     return static_cast<IPAddress>(ips_.at(0));
971   }
972 
973   InterfaceAddress selected_ip, ula_ip;
974 
975   for (const InterfaceAddress& ip : ips_) {
976     // Ignore any address which has been deprecated already.
977     if (ip.ipv6_flags() & IPV6_ADDRESS_FLAG_DEPRECATED)
978       continue;
979 
980     // ULA address should only be returned when we have no other
981     // global IP.
982     if (IPIsULA(static_cast<const IPAddress&>(ip))) {
983       ula_ip = ip;
984       continue;
985     }
986     selected_ip = ip;
987 
988     // Search could stop once a temporary non-deprecated one is found.
989     if (ip.ipv6_flags() & IPV6_ADDRESS_FLAG_TEMPORARY)
990       break;
991   }
992 
993   // No proper global IPv6 address found, use ULA instead.
994   if (IPIsUnspec(selected_ip) && !IPIsUnspec(ula_ip)) {
995     selected_ip = ula_ip;
996   }
997 
998   return static_cast<IPAddress>(selected_ip);
999 }
1000 
GetMdnsResponder() const1001 webrtc::MdnsResponderInterface* Network::GetMdnsResponder() const {
1002   if (mdns_responder_provider_ == nullptr) {
1003     return nullptr;
1004   }
1005   return mdns_responder_provider_->GetMdnsResponder();
1006 }
1007 
GetCost() const1008 uint16_t Network::GetCost() const {
1009   AdapterType type = IsVpn() ? underlying_type_for_vpn_ : type_;
1010   return ComputeNetworkCostByType(type);
1011 }
1012 
ToString() const1013 std::string Network::ToString() const {
1014   rtc::StringBuilder ss;
1015   // Print out the first space-terminated token of the network desc, plus
1016   // the IP address.
1017   ss << "Net[" << description_.substr(0, description_.find(' ')) << ":"
1018      << prefix_.ToSensitiveString() << "/" << prefix_length_ << ":"
1019      << AdapterTypeToString(type_);
1020   if (IsVpn()) {
1021     ss << "/" << AdapterTypeToString(underlying_type_for_vpn_);
1022   }
1023   ss << ":id=" << id_ << "]";
1024   return ss.Release();
1025 }
1026 
1027 }  // namespace rtc
1028