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