summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/libjingle/source/talk/base/network.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/libjingle/source/talk/base/network.cc')
-rw-r--r--chromium/third_party/libjingle/source/talk/base/network.cc119
1 files changed, 101 insertions, 18 deletions
diff --git a/chromium/third_party/libjingle/source/talk/base/network.cc b/chromium/third_party/libjingle/source/talk/base/network.cc
index d4dda138135..829507aec7d 100644
--- a/chromium/third_party/libjingle/source/talk/base/network.cc
+++ b/chromium/third_party/libjingle/source/talk/base/network.cc
@@ -38,7 +38,7 @@
#if defined(ANDROID) || defined(LINUX)
#include <linux/if.h>
#include <linux/route.h>
-#else
+#elif !defined(__native_client__)
#include <net/if.h>
#endif
#include <sys/socket.h>
@@ -46,11 +46,13 @@
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
+
#ifdef ANDROID
#include "talk/base/ifaddrs-android.h"
-#else
+#elif !defined(__native_client__)
#include <ifaddrs.h>
#endif
+
#endif // POSIX
#ifdef WIN32
@@ -58,8 +60,9 @@
#include <Iphlpapi.h>
#endif
+#include <stdio.h>
+
#include <algorithm>
-#include <cstdio>
#include "talk/base/logging.h"
#include "talk/base/scoped_ptr.h"
@@ -77,16 +80,7 @@ const uint32 kSignalNetworksMessage = 2;
// Fetch list of networks every two seconds.
const int kNetworksUpdateIntervalMs = 2000;
-
-// Makes a string key for this network. Used in the network manager's maps.
-// Network objects are keyed on interface name, network prefix and the
-// length of that prefix.
-std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
- int prefix_length) {
- std::ostringstream ost;
- ost << name << "%" << prefix.ToString() << "/" << prefix_length;
- return ost.str();
-}
+const int kHighestNetworkPreference = 127;
bool CompareNetworks(const Network* a, const Network* b) {
if (a->prefix_length() == b->prefix_length()) {
@@ -97,9 +91,54 @@ bool CompareNetworks(const Network* a, const Network* b) {
return a->name() < b->name();
}
+bool SortNetworks(const Network* a, const Network* b) {
+ // Network types will be preferred above everything else while sorting
+ // Networks.
+
+ // Networks are sorted first by type.
+ if (a->type() != b->type()) {
+ return a->type() < b->type();
+ }
+
+ // After type, networks are sorted by IP address precedence values
+ // from RFC 3484-bis
+ if (IPAddressPrecedence(a->ip()) != IPAddressPrecedence(b->ip())) {
+ return IPAddressPrecedence(a->ip()) > IPAddressPrecedence(b->ip());
+ }
+
+ // TODO(mallinath) - Add VPN and Link speed conditions while sorting.
+
+ // Networks are sorted last by key.
+ return a->key() > b->key();
+}
+
+std::string AdapterTypeToString(AdapterType type) {
+ switch (type) {
+ case ADAPTER_TYPE_UNKNOWN:
+ return "Unknown";
+ case ADAPTER_TYPE_ETHERNET:
+ return "Ethernet";
+ case ADAPTER_TYPE_WIFI:
+ return "Wifi";
+ case ADAPTER_TYPE_CELLULAR:
+ return "Cellular";
+ case ADAPTER_TYPE_VPN:
+ return "VPN";
+ default:
+ ASSERT(false);
+ return std::string();
+ }
+}
} // namespace
+std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
+ int prefix_length) {
+ std::ostringstream ost;
+ ost << name << "%" << prefix.ToString() << "/" << prefix_length;
+ return ost.str();
+}
+
NetworkManager::NetworkManager() {
}
@@ -178,6 +217,29 @@ void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
}
}
networks_ = merged_list;
+
+ // If the network lists changes, we resort it.
+ if (changed) {
+ std::sort(networks_.begin(), networks_.end(), SortNetworks);
+ // Now network interfaces are sorted, we should set the preference value
+ // for each of the interfaces we are planning to use.
+ // Preference order of network interfaces might have changed from previous
+ // sorting due to addition of higher preference network interface.
+ // Since we have already sorted the network interfaces based on our
+ // requirements, we will just assign a preference value starting with 127,
+ // in decreasing order.
+ int pref = kHighestNetworkPreference;
+ for (NetworkList::const_iterator iter = networks_.begin();
+ iter != networks_.end(); ++iter) {
+ (*iter)->set_preference(pref);
+ if (pref > 0) {
+ --pref;
+ } else {
+ LOG(LS_ERROR) << "Too many network interfaces to handle!";
+ break;
+ }
+ }
+ }
}
BasicNetworkManager::BasicNetworkManager()
@@ -188,7 +250,16 @@ BasicNetworkManager::BasicNetworkManager()
BasicNetworkManager::~BasicNetworkManager() {
}
-#if defined(POSIX)
+#if defined(__native_client__)
+
+bool BasicNetworkManager::CreateNetworks(bool include_ignored,
+ NetworkList* networks) const {
+ ASSERT(false);
+ LOG(LS_WARNING) << "BasicNetworkManager doesn't work on NaCl yet";
+ return false;
+}
+
+#elif defined(POSIX)
void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
bool include_ignored,
NetworkList* networks) const {
@@ -229,6 +300,7 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
continue;
}
}
+
int prefix_length = CountIPMaskBits(mask);
prefix = TruncateIP(ip, prefix_length);
std::string key = MakeNetworkKey(std::string(cursor->ifa_name),
@@ -375,6 +447,7 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
continue;
}
}
+
IPAddress prefix;
int prefix_length = GetPrefix(prefixlist, ip, &prefix);
std::string key = MakeNetworkKey(name, prefix, prefix_length);
@@ -553,9 +626,17 @@ void BasicNetworkManager::DumpNetworks(bool include_ignored) {
Network::Network(const std::string& name, const std::string& desc,
const IPAddress& prefix, int prefix_length)
: name_(name), description_(desc), prefix_(prefix),
- prefix_length_(prefix_length), scope_id_(0), ignored_(false),
- uniform_numerator_(0), uniform_denominator_(0), exponential_numerator_(0),
- exponential_denominator_(0) {
+ prefix_length_(prefix_length),
+ key_(MakeNetworkKey(name, prefix, prefix_length)), scope_id_(0),
+ ignored_(false), type_(ADAPTER_TYPE_UNKNOWN), preference_(0) {
+}
+
+Network::Network(const std::string& name, const std::string& desc,
+ const IPAddress& prefix, int prefix_length, AdapterType type)
+ : name_(name), description_(desc), prefix_(prefix),
+ prefix_length_(prefix_length),
+ key_(MakeNetworkKey(name, prefix, prefix_length)), scope_id_(0),
+ ignored_(false), type_(type), preference_(0) {
}
std::string Network::ToString() const {
@@ -563,7 +644,8 @@ std::string Network::ToString() const {
// Print out the first space-terminated token of the network desc, plus
// the IP address.
ss << "Net[" << description_.substr(0, description_.find(' '))
- << ":" << prefix_.ToSensitiveString() << "/" << prefix_length_ << "]";
+ << ":" << prefix_.ToSensitiveString() << "/" << prefix_length_
+ << ":" << AdapterTypeToString(type_) << "]";
return ss.str();
}
@@ -589,4 +671,5 @@ bool Network::SetIPs(const std::vector<IPAddress>& ips, bool changed) {
ips_ = ips;
return changed;
}
+
} // namespace talk_base