summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorAndroid Chromium Automerger <chromium-automerger@android>2014-09-19 09:22:44 +0000
committerAndroid Chromium Automerger <chromium-automerger@android>2014-09-19 09:22:44 +0000
commitbd420037581c79bb3b2044174afca79eeea44a11 (patch)
tree520287502c66ca66368735ac179c6c931d1357df /base
parenta4c22e952c058c276f970ee863e7b599399a2d7b (diff)
parent70861e04b3580c1350c5479c9ee26469f38ff782 (diff)
downloadwebrtc-bd420037581c79bb3b2044174afca79eeea44a11.tar.gz
Merge third_party/webrtc from https://chromium.googlesource.com/external/webrtc/trunk/webrtc.git at 70861e04b3580c1350c5479c9ee26469f38ff782
This commit was generated by merge_from_chromium.py. Change-Id: Ib21179e777d68b7a3deb3e39851d6f26ffd72b39
Diffstat (limited to 'base')
-rw-r--r--base/nat_unittest.cc2
-rw-r--r--base/network.cc67
-rw-r--r--base/network.h31
-rw-r--r--base/network_unittest.cc43
-rw-r--r--base/thread.cc63
-rw-r--r--base/thread.h26
-rw-r--r--base/thread_unittest.cc10
7 files changed, 173 insertions, 69 deletions
diff --git a/base/nat_unittest.cc b/base/nat_unittest.cc
index 8b9d8a15..0e16259a 100644
--- a/base/nat_unittest.cc
+++ b/base/nat_unittest.cc
@@ -209,7 +209,7 @@ void TestPhysicalInternal(const SocketAddress& int_addr) {
// can't talk to ip, so check for connectivity as well.
for (std::vector<Network*>::iterator it = networks.begin();
it != networks.end(); ++it) {
- const IPAddress& ip = (*it)->ip();
+ const IPAddress& ip = (*it)->GetBestIP();
if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) {
ext_addr2.SetIP(ip);
break;
diff --git a/base/network.cc b/base/network.cc
index 8c84c2e3..c1f978b9 100644
--- a/base/network.cc
+++ b/base/network.cc
@@ -88,10 +88,13 @@ bool SortNetworks(const Network* a, const Network* b) {
return a->type() < b->type();
}
+ IPAddress ip_a = a->GetBestIP();
+ IPAddress ip_b = b->GetBestIP();
+
// 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());
+ if (IPAddressPrecedence(ip_a) != IPAddressPrecedence(ip_b)) {
+ return IPAddressPrecedence(ip_a) > IPAddressPrecedence(ip_b);
}
// TODO(mallinath) - Add VPN and Link speed conditions while sorting.
@@ -474,7 +477,7 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
}
return true;
}
-#endif // WEBRTC_WIN
+#endif // WEBRTC_WIN
#if defined(WEBRTC_LINUX)
bool IsDefaultRoute(const std::string& network_name) {
@@ -636,16 +639,6 @@ Network::Network(const std::string& name, const std::string& desc,
ignored_(false), type_(type), preference_(0) {
}
-std::string Network::ToString() const {
- std::stringstream ss;
- // 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_
- << ":" << AdapterTypeToString(type_) << "]";
- return ss.str();
-}
-
// Sets the addresses of this network. Returns true if the address set changed.
// Change detection is short circuited if the changed argument is true.
bool Network::SetIPs(const std::vector<InterfaceAddress>& ips, bool changed) {
@@ -669,14 +662,52 @@ bool Network::SetIPs(const std::vector<InterfaceAddress>& ips, bool changed) {
return changed;
}
-// TODO(guoweis): will change the name to a more meaningful name as
-// this is not simply return the first address once the logic of ipv6
-// address selection is complete.
-IPAddress Network::ip() const {
+// Select the best IP address to use from this Network.
+IPAddress Network::GetBestIP() const {
if (ips_.size() == 0) {
return IPAddress();
}
- return static_cast<IPAddress>(ips_.at(0));
+
+ if (prefix_.family() == AF_INET) {
+ return static_cast<IPAddress>(ips_.at(0));
+ }
+
+ InterfaceAddress selected_ip, ula_ip;
+
+ for (size_t i = 0; i < ips_.size(); i++) {
+ // Ignore any address which has been deprecated already.
+ if (ips_[i].ipv6_flags() & IPV6_ADDRESS_FLAG_DEPRECATED)
+ continue;
+
+ // ULA address should only be returned when we have no other
+ // global IP.
+ if (IPIsULA(static_cast<const IPAddress&>(ips_[i]))) {
+ ula_ip = ips_[i];
+ continue;
+ }
+ selected_ip = ips_[i];
+
+ // Search could stop once a temporary non-deprecated one is found.
+ if (ips_[i].ipv6_flags() & IPV6_ADDRESS_FLAG_TEMPORARY)
+ break;
+ }
+
+ // No proper global IPv6 address found, use ULA instead.
+ if (IPIsUnspec(selected_ip) && !IPIsUnspec(ula_ip)) {
+ selected_ip = ula_ip;
+ }
+
+ return static_cast<IPAddress>(selected_ip);
+}
+
+std::string Network::ToString() const {
+ std::stringstream ss;
+ // 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_
+ << ":" << AdapterTypeToString(type_) << "]";
+ return ss.str();
}
} // namespace rtc
diff --git a/base/network.h b/base/network.h
index 4cdd4d8e..6f9d08e7 100644
--- a/base/network.h
+++ b/base/network.h
@@ -188,19 +188,28 @@ class Network {
std::string key() const { return key_; }
// Returns the Network's current idea of the 'best' IP it has.
- // 'Best' currently means the first one added.
- // Returns an unset IP if this network has no active addresses.
- // Here is the rule on how we mark the IPv6 address as ignorable for webrtc.
+ // Or return an unset IP if this network has no active addresses.
+ // Here is the rule on how we mark the IPv6 address as ignorable for WebRTC.
// 1) return all global temporary dynamic and non-deprecrated ones.
- // 2) if #1 not available, return global dynamic ones.
- // 3) if #2 not available, return global ones.
- // 4) if #3 not available, use ULA ipv6 as last resort.
+ // 2) if #1 not available, return global ones.
+ // 3) if #2 not available, use ULA ipv6 as last resort. (ULA stands
+ // for unique local address, which is not route-able in open
+ // internet but might be useful for a close WebRTC deployment.
+
+ // TODO(guoweis): rule #3 actually won't happen at current
+ // implementation. The reason being that ULA address starting with
+ // 0xfc 0r 0xfd will be grouped into its own Network. The result of
+ // that is WebRTC will have one extra Network to generate candidates
+ // but the lack of rule #3 shouldn't prevent turning on IPv6 since
+ // ULA should only be tried in a close deployment anyway.
+
// Note that when not specifying any flag, it's treated as case global
- // dynamic IPv6 address
- // TODO(guoweis): will change the name to a more meaningful name as
- // this is not simply return the first address once the logic of ipv6
- // address selection is complete.
- IPAddress ip() const;
+ // IPv6 address
+ IPAddress GetBestIP() const;
+
+ // Keep the original function here for now.
+ // TODO(guoweis): Remove this when all callers are migrated to GetBestIP().
+ IPAddress ip() const { return GetBestIP(); }
// Adds an active IP address to this network. Does not check for duplicates.
void AddIP(const InterfaceAddress& ip) { ips_.push_back(ip); }
diff --git a/base/network_unittest.cc b/base/network_unittest.cc
index 8123f8bb..acb118d4 100644
--- a/base/network_unittest.cc
+++ b/base/network_unittest.cc
@@ -114,7 +114,7 @@ TEST_F(NetworkTest, DISABLED_TestCreateNetworks) {
++it) {
sockaddr_storage storage;
memset(&storage, 0, sizeof(storage));
- IPAddress ip = (*it)->ip();
+ IPAddress ip = (*it)->GetBestIP();
SocketAddress bindaddress(ip, 0);
bindaddress.SetScopeID((*it)->scope_id());
// TODO(thaloun): Use rtc::AsyncSocket once it supports IPv6.
@@ -650,4 +650,45 @@ TEST_F(NetworkTest, TestMergeNetworkList) {
EXPECT_EQ(list2[0]->GetIPs()[1], ip2);
}
+// Test that the filtering logic follows the defined ruleset in network.h.
+TEST_F(NetworkTest, TestIPv6Selection) {
+ InterfaceAddress ip;
+ std::string ipstr;
+
+ ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c3";
+ ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_DEPRECATED, &ip));
+
+ // Create a network with this prefix.
+ Network ipv6_network(
+ "test_eth0", "Test NetworkAdapter", TruncateIP(ip, 64), 64);
+
+ // When there is no address added, it should return an unspecified
+ // address.
+ EXPECT_EQ(ipv6_network.GetBestIP(), IPAddress());
+ EXPECT_TRUE(IPIsUnspec(ipv6_network.GetBestIP()));
+
+ // Deprecated one should not be returned.
+ ipv6_network.AddIP(ip);
+ EXPECT_EQ(ipv6_network.GetBestIP(), IPAddress());
+
+ // Add ULA one. ULA is unique local address which is starting either
+ // with 0xfc or 0xfd.
+ ipstr = "fd00:fa00:4:1000:be30:5bff:fee5:c4";
+ ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &ip));
+ ipv6_network.AddIP(ip);
+ EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
+
+ // Add global one.
+ ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c5";
+ ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &ip));
+ ipv6_network.AddIP(ip);
+ EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
+
+ // Add global dynamic temporary one.
+ ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c6";
+ ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_TEMPORARY, &ip));
+ ipv6_network.AddIP(ip);
+ EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
+}
+
} // namespace rtc
diff --git a/base/thread.cc b/base/thread.cc
index 6da9a7fb..9d2917d9 100644
--- a/base/thread.cc
+++ b/base/thread.cc
@@ -107,7 +107,7 @@ Thread *ThreadManager::WrapCurrentThread() {
Thread* result = CurrentThread();
if (NULL == result) {
result = new Thread();
- result->WrapCurrentWithThreadManager(this);
+ result->WrapCurrentWithThreadManager(this, true);
}
return result;
}
@@ -188,6 +188,7 @@ bool Thread::SetName(const std::string& name, const void* obj) {
bool Thread::SetPriority(ThreadPriority priority) {
#if defined(WEBRTC_WIN)
if (running()) {
+ ASSERT(thread_ != NULL);
BOOL ret = FALSE;
if (priority == PRIORITY_NORMAL) {
ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_NORMAL);
@@ -288,12 +289,35 @@ bool Thread::Start(Runnable* runnable) {
return true;
}
+bool Thread::WrapCurrent() {
+ return WrapCurrentWithThreadManager(ThreadManager::Instance(), true);
+}
+
+void Thread::UnwrapCurrent() {
+ // Clears the platform-specific thread-specific storage.
+ ThreadManager::Instance()->SetCurrentThread(NULL);
+#if defined(WEBRTC_WIN)
+ if (thread_ != NULL) {
+ if (!CloseHandle(thread_)) {
+ LOG_GLE(LS_ERROR) << "When unwrapping thread, failed to close handle.";
+ }
+ thread_ = NULL;
+ }
+#endif
+ running_.Reset();
+}
+
+void Thread::SafeWrapCurrent() {
+ WrapCurrentWithThreadManager(ThreadManager::Instance(), false);
+}
+
void Thread::Join() {
AssertBlockingIsAllowedOnCurrentThread();
if (running()) {
ASSERT(!IsCurrent());
#if defined(WEBRTC_WIN)
+ ASSERT(thread_ != NULL);
WaitForSingleObject(thread_, INFINITE);
CloseHandle(thread_);
thread_ = NULL;
@@ -526,43 +550,32 @@ bool Thread::ProcessMessages(int cmsLoop) {
}
}
-bool Thread::WrapCurrent() {
- return WrapCurrentWithThreadManager(ThreadManager::Instance());
-}
-
-bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager) {
+bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager,
+ bool need_synchronize_access) {
if (running())
return false;
+
#if defined(WEBRTC_WIN)
- // We explicitly ask for no rights other than synchronization.
- // This gives us the best chance of succeeding.
- thread_ = OpenThread(SYNCHRONIZE, FALSE, GetCurrentThreadId());
- if (!thread_) {
- LOG_GLE(LS_ERROR) << "Unable to get handle to thread.";
- return false;
+ if (need_synchronize_access) {
+ // We explicitly ask for no rights other than synchronization.
+ // This gives us the best chance of succeeding.
+ thread_ = OpenThread(SYNCHRONIZE, FALSE, GetCurrentThreadId());
+ if (!thread_) {
+ LOG_GLE(LS_ERROR) << "Unable to get handle to thread.";
+ return false;
+ }
+ thread_id_ = GetCurrentThreadId();
}
- thread_id_ = GetCurrentThreadId();
#elif defined(WEBRTC_POSIX)
thread_ = pthread_self();
#endif
+
owned_ = false;
running_.Set();
thread_manager->SetCurrentThread(this);
return true;
}
-void Thread::UnwrapCurrent() {
- // Clears the platform-specific thread-specific storage.
- ThreadManager::Instance()->SetCurrentThread(NULL);
-#if defined(WEBRTC_WIN)
- if (!CloseHandle(thread_)) {
- LOG_GLE(LS_ERROR) << "When unwrapping thread, failed to close handle.";
- }
-#endif
- running_.Reset();
-}
-
-
AutoThread::AutoThread(SocketServer* ss) : Thread(ss) {
if (!ThreadManager::Instance()->CurrentThread()) {
ThreadManager::Instance()->SetCurrentThread(this);
diff --git a/base/thread.h b/base/thread.h
index 742ba6dc..25b0f569 100644
--- a/base/thread.h
+++ b/base/thread.h
@@ -202,15 +202,6 @@ class Thread : public MessageQueue {
}
#endif
- // This method should be called when thread is created using non standard
- // method, like derived implementation of rtc::Thread and it can not be
- // started by calling Start(). This will set started flag to true and
- // owned to false. This must be called from the current thread.
- // NOTE: These methods should be used by the derived classes only, added here
- // only for testing.
- bool WrapCurrent();
- void UnwrapCurrent();
-
// Expose private method running() for tests.
//
// DANGER: this is a terrible public API. Most callers that might want to
@@ -220,6 +211,18 @@ class Thread : public MessageQueue {
bool RunningForTest() { return running(); }
protected:
+ // This method should be called when thread is created using non standard
+ // method, like derived implementation of rtc::Thread and it can not be
+ // started by calling Start(). This will set started flag to true and
+ // owned to false. This must be called from the current thread.
+ bool WrapCurrent();
+ void UnwrapCurrent();
+
+ // Same as WrapCurrent except that it never fails as it does not try to
+ // acquire the synchronization access of the thread. The caller should never
+ // call Stop() or Join() on this thread.
+ void SafeWrapCurrent();
+
// Blocks the calling thread until this thread has terminated.
void Join();
@@ -237,7 +240,10 @@ class Thread : public MessageQueue {
// ThreadManager calls this instead WrapCurrent() because
// ThreadManager::Instance() cannot be used while ThreadManager is
// being created.
- bool WrapCurrentWithThreadManager(ThreadManager* thread_manager);
+ // The method tries to get synchronization rights of the thread on Windows if
+ // |need_synchronize_access| is true.
+ bool WrapCurrentWithThreadManager(ThreadManager* thread_manager,
+ bool need_synchronize_access);
// Return true if the thread was started and hasn't yet stopped.
bool running() { return running_.Wait(0); }
diff --git a/base/thread_unittest.cc b/base/thread_unittest.cc
index 6a54ac7b..6a687574 100644
--- a/base/thread_unittest.cc
+++ b/base/thread_unittest.cc
@@ -105,6 +105,13 @@ class CustomThread : public rtc::Thread {
CustomThread() {}
virtual ~CustomThread() { Stop(); }
bool Start() { return false; }
+
+ bool WrapCurrent() {
+ return Thread::WrapCurrent();
+ }
+ void UnwrapCurrent() {
+ Thread::UnwrapCurrent();
+ }
};
@@ -240,8 +247,6 @@ TEST(ThreadTest, Priorities) {
}
TEST(ThreadTest, Wrap) {
- Thread* current_thread = Thread::Current();
- current_thread->UnwrapCurrent();
CustomThread* cthread = new CustomThread();
EXPECT_TRUE(cthread->WrapCurrent());
EXPECT_TRUE(cthread->RunningForTest());
@@ -249,7 +254,6 @@ TEST(ThreadTest, Wrap) {
cthread->UnwrapCurrent();
EXPECT_FALSE(cthread->RunningForTest());
delete cthread;
- current_thread->WrapCurrent();
}
TEST(ThreadTest, Invoke) {