diff options
author | Android Chromium Automerger <chromium-automerger@android> | 2014-09-19 09:22:44 +0000 |
---|---|---|
committer | Android Chromium Automerger <chromium-automerger@android> | 2014-09-19 09:22:44 +0000 |
commit | bd420037581c79bb3b2044174afca79eeea44a11 (patch) | |
tree | 520287502c66ca66368735ac179c6c931d1357df /base | |
parent | a4c22e952c058c276f970ee863e7b599399a2d7b (diff) | |
parent | 70861e04b3580c1350c5479c9ee26469f38ff782 (diff) | |
download | webrtc-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.cc | 2 | ||||
-rw-r--r-- | base/network.cc | 67 | ||||
-rw-r--r-- | base/network.h | 31 | ||||
-rw-r--r-- | base/network_unittest.cc | 43 | ||||
-rw-r--r-- | base/thread.cc | 63 | ||||
-rw-r--r-- | base/thread.h | 26 | ||||
-rw-r--r-- | base/thread_unittest.cc | 10 |
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) { |