Implemented Network::GetBestIP() selection logic as following.

1) return the first global temporary and non-deprecrated ones.
2) if #1 not available, return global one.
3) if #2 not available, use ULA ipv6 as last resort.

ULA stands for unique local address. They are only useful in a private
WebRTC deployment. More detail: http://en.wikipedia.org/wiki/Unique_local_address

BUG=3808

At this point, 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.

R=jiayl@webrtc.org

Committed: https://code.google.com/p/webrtc/source/detail?r=7200

Review URL: https://webrtc-codereview.appspot.com/31369004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7201 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
guoweis@webrtc.org 2014-09-16 20:29:41 +00:00
parent f8bff762d1
commit 40c2aa36f2
8 changed files with 67 additions and 238 deletions

View File

@ -431,7 +431,7 @@ void BasicPortAllocatorSession::DoAllocate() {
} }
if (!(sequence_flags & PORTALLOCATOR_ENABLE_IPV6) && if (!(sequence_flags & PORTALLOCATOR_ENABLE_IPV6) &&
networks[i]->GetBestIP().family() == AF_INET6) { networks[i]->ip().family() == AF_INET6) {
// Skip IPv6 networks unless the flag's been set. // Skip IPv6 networks unless the flag's been set.
continue; continue;
} }
@ -728,7 +728,7 @@ AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session,
uint32 flags) uint32 flags)
: session_(session), : session_(session),
network_(network), network_(network),
ip_(network->GetBestIP()), ip_(network->ip()),
config_(config), config_(config),
state_(kInit), state_(kInit),
flags_(flags), flags_(flags),
@ -771,7 +771,7 @@ AllocationSequence::~AllocationSequence() {
void AllocationSequence::DisableEquivalentPhases(rtc::Network* network, void AllocationSequence::DisableEquivalentPhases(rtc::Network* network,
PortConfiguration* config, uint32* flags) { PortConfiguration* config, uint32* flags) {
if (!((network == network_) && (ip_ == network->GetBestIP()))) { if (!((network == network_) && (ip_ == network->ip()))) {
// Different network setup; nothing is equivalent. // Different network setup; nothing is equivalent.
return; return;
} }

View File

@ -1,29 +1,5 @@
/* // Copyright 2011 Google Inc. All Rights Reserved.
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string> #include <string>
@ -238,8 +214,7 @@ void ConnectivityChecker::OnRequestDone(rtc::AsyncHttpRequest* request) {
return; return;
} }
rtc::ProxyInfo proxy_info = request->proxy(); rtc::ProxyInfo proxy_info = request->proxy();
NicMap::iterator i = NicMap::iterator i = nics_.find(NicId(networks[0]->ip(), proxy_info.address));
nics_.find(NicId(networks[0]->GetBestIP(), proxy_info.address));
if (i != nics_.end()) { if (i != nics_.end()) {
int port = request->port(); int port = request->port();
uint32 now = rtc::Time(); uint32 now = rtc::Time();
@ -272,7 +247,7 @@ void ConnectivityChecker::OnRelayPortComplete(Port* port) {
ASSERT(worker_ == rtc::Thread::Current()); ASSERT(worker_ == rtc::Thread::Current());
RelayPort* relay_port = reinterpret_cast<RelayPort*>(port); RelayPort* relay_port = reinterpret_cast<RelayPort*>(port);
const ProtocolAddress* address = relay_port->ServerAddress(0); const ProtocolAddress* address = relay_port->ServerAddress(0);
rtc::IPAddress ip = port->Network()->GetBestIP(); rtc::IPAddress ip = port->Network()->ip();
NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address)); NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address));
if (i != nics_.end()) { if (i != nics_.end()) {
// We have it already, add the new information. // We have it already, add the new information.
@ -306,7 +281,7 @@ void ConnectivityChecker::OnStunPortComplete(Port* port) {
ASSERT(worker_ == rtc::Thread::Current()); ASSERT(worker_ == rtc::Thread::Current());
const std::vector<Candidate> candidates = port->Candidates(); const std::vector<Candidate> candidates = port->Candidates();
Candidate c = candidates[0]; Candidate c = candidates[0];
rtc::IPAddress ip = port->Network()->GetBestIP(); rtc::IPAddress ip = port->Network()->ip();
NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address)); NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address));
if (i != nics_.end()) { if (i != nics_.end()) {
// We have it already, add the new information. // We have it already, add the new information.
@ -325,7 +300,7 @@ void ConnectivityChecker::OnStunPortComplete(Port* port) {
void ConnectivityChecker::OnStunPortError(Port* port) { void ConnectivityChecker::OnStunPortError(Port* port) {
ASSERT(worker_ == rtc::Thread::Current()); ASSERT(worker_ == rtc::Thread::Current());
LOG(LS_ERROR) << "Stun address error."; LOG(LS_ERROR) << "Stun address error.";
rtc::IPAddress ip = port->Network()->GetBestIP(); rtc::IPAddress ip = port->Network()->ip();
NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address)); NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address));
if (i != nics_.end()) { if (i != nics_.end()) {
// We have it already, add the new information. // We have it already, add the new information.
@ -362,28 +337,19 @@ HttpPortAllocator* ConnectivityChecker::CreatePortAllocator(
StunPort* ConnectivityChecker::CreateStunPort( StunPort* ConnectivityChecker::CreateStunPort(
const std::string& username, const std::string& password, const std::string& username, const std::string& password,
const PortConfiguration* config, rtc::Network* network) { const PortConfiguration* config, rtc::Network* network) {
return StunPort::Create(worker_, return StunPort::Create(worker_, socket_factory_.get(),
socket_factory_.get(), network, network->ip(), 0, 0,
network, username, password, config->stun_servers);
network->GetBestIP(),
0,
0,
username,
password,
config->stun_servers);
} }
RelayPort* ConnectivityChecker::CreateRelayPort( RelayPort* ConnectivityChecker::CreateRelayPort(
const std::string& username, const std::string& password, const std::string& username, const std::string& password,
const PortConfiguration* config, rtc::Network* network) { const PortConfiguration* config, rtc::Network* network) {
return RelayPort::Create(worker_, return RelayPort::Create(worker_, socket_factory_.get(),
socket_factory_.get(), network, network->ip(),
network,
network->GetBestIP(),
port_allocator_->min_port(), port_allocator_->min_port(),
port_allocator_->max_port(), port_allocator_->max_port(),
username, username, password);
password);
} }
void ConnectivityChecker::CreateRelayPorts( void ConnectivityChecker::CreateRelayPorts(
@ -399,8 +365,8 @@ void ConnectivityChecker::CreateRelayPorts(
for (relay = config->relays.begin(); for (relay = config->relays.begin();
relay != config->relays.end(); ++relay) { relay != config->relays.end(); ++relay) {
for (uint32 i = 0; i < networks.size(); ++i) { for (uint32 i = 0; i < networks.size(); ++i) {
NicMap::iterator iter = NicMap::iterator iter = nics_.find(NicId(networks[i]->ip(),
nics_.find(NicId(networks[i]->GetBestIP(), proxy_info.address)); proxy_info.address));
if (iter != nics_.end()) { if (iter != nics_.end()) {
// TODO: Now setting the same start time for all protocols. // TODO: Now setting the same start time for all protocols.
// This might affect accuracy, but since we are mainly looking for // This might affect accuracy, but since we are mainly looking for
@ -457,7 +423,7 @@ void ConnectivityChecker::AllocatePorts() {
rtc::ProxyInfo proxy_info = GetProxyInfo(); rtc::ProxyInfo proxy_info = GetProxyInfo();
bool allocate_relay_ports = false; bool allocate_relay_ports = false;
for (uint32 i = 0; i < networks.size(); ++i) { for (uint32 i = 0; i < networks.size(); ++i) {
if (AddNic(networks[i]->GetBestIP(), proxy_info.address)) { if (AddNic(networks[i]->ip(), proxy_info.address)) {
Port* port = CreateStunPort(username, password, &config, networks[i]); Port* port = CreateStunPort(username, password, &config, networks[i]);
if (port) { if (port) {
@ -534,8 +500,7 @@ void ConnectivityChecker::RegisterHttpStart(int port) {
return; return;
} }
rtc::ProxyInfo proxy_info = GetProxyInfo(); rtc::ProxyInfo proxy_info = GetProxyInfo();
NicMap::iterator i = NicMap::iterator i = nics_.find(NicId(networks[0]->ip(), proxy_info.address));
nics_.find(NicId(networks[0]->GetBestIP(), proxy_info.address));
if (i != nics_.end()) { if (i != nics_.end()) {
uint32 now = rtc::Time(); uint32 now = rtc::Time();
NicInfo* nic_info = &i->second; NicInfo* nic_info = &i->second;

View File

@ -1,29 +1,5 @@
/* // Copyright 2011 Google Inc. All Rights Reserved.
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string> #include <string>
@ -235,27 +211,19 @@ class ConnectivityCheckerForTest : public ConnectivityChecker {
virtual StunPort* CreateStunPort( virtual StunPort* CreateStunPort(
const std::string& username, const std::string& password, const std::string& username, const std::string& password,
const PortConfiguration* config, rtc::Network* network) { const PortConfiguration* config, rtc::Network* network) {
return new FakeStunPort(worker(), return new FakeStunPort(worker(), socket_factory_,
socket_factory_, network, network->ip(),
network, kMinPort, kMaxPort,
network->GetBestIP(), username, password,
kMinPort,
kMaxPort,
username,
password,
config->stun_servers); config->stun_servers);
} }
virtual RelayPort* CreateRelayPort( virtual RelayPort* CreateRelayPort(
const std::string& username, const std::string& password, const std::string& username, const std::string& password,
const PortConfiguration* config, rtc::Network* network) { const PortConfiguration* config, rtc::Network* network) {
return new FakeRelayPort(worker(), return new FakeRelayPort(worker(), socket_factory_,
socket_factory_, network, network->ip(),
network, kMinPort, kMaxPort,
network->GetBestIP(), username, password);
kMinPort,
kMaxPort,
username,
password);
} }
virtual void InitiateProxyDetection() { virtual void InitiateProxyDetection() {
if (!proxy_initiated_) { if (!proxy_initiated_) {

View File

@ -1,29 +1,6 @@
/* // Copyright 2010 Google Inc. All Rights Reserved,
* libjingle //
* Copyright 2004--2005, Google Inc. // Author: Justin Uberti (juberti@google.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TALK_P2P_CLIENT_FAKEPORTALLOCATOR_H_ #ifndef TALK_P2P_CLIENT_FAKEPORTALLOCATOR_H_
#define TALK_P2P_CLIENT_FAKEPORTALLOCATOR_H_ #define TALK_P2P_CLIENT_FAKEPORTALLOCATOR_H_
@ -62,14 +39,10 @@ class FakePortAllocatorSession : public PortAllocatorSession {
virtual void StartGettingPorts() { virtual void StartGettingPorts() {
if (!port_) { if (!port_) {
port_.reset(cricket::UDPPort::Create(worker_thread_, port_.reset(cricket::UDPPort::Create(worker_thread_, factory_,
factory_, &network_, network_.ip(), 0, 0,
&network_, username(),
network_.GetBestIP(), password()));
0,
0,
username(),
password()));
AddPort(port_.get()); AddPort(port_.get());
} }
++port_config_count_; ++port_config_count_;

View File

@ -209,7 +209,7 @@ void TestPhysicalInternal(const SocketAddress& int_addr) {
// can't talk to ip, so check for connectivity as well. // can't talk to ip, so check for connectivity as well.
for (std::vector<Network*>::iterator it = networks.begin(); for (std::vector<Network*>::iterator it = networks.begin();
it != networks.end(); ++it) { it != networks.end(); ++it) {
const IPAddress& ip = (*it)->GetBestIP(); const IPAddress& ip = (*it)->ip();
if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) { if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) {
ext_addr2.SetIP(ip); ext_addr2.SetIP(ip);
break; break;

View File

@ -88,13 +88,10 @@ bool SortNetworks(const Network* a, const Network* b) {
return a->type() < b->type(); 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 // After type, networks are sorted by IP address precedence values
// from RFC 3484-bis // from RFC 3484-bis
if (IPAddressPrecedence(ip_a) != IPAddressPrecedence(ip_b)) { if (IPAddressPrecedence(a->ip()) != IPAddressPrecedence(b->ip())) {
return IPAddressPrecedence(ip_a) > IPAddressPrecedence(ip_b); return IPAddressPrecedence(a->ip()) > IPAddressPrecedence(b->ip());
} }
// TODO(mallinath) - Add VPN and Link speed conditions while sorting. // TODO(mallinath) - Add VPN and Link speed conditions while sorting.
@ -477,7 +474,7 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
} }
return true; return true;
} }
#endif // WEBRTC_WIN #endif // WEBRTC_WIN
#if defined(WEBRTC_LINUX) #if defined(WEBRTC_LINUX)
bool IsDefaultRoute(const std::string& network_name) { bool IsDefaultRoute(const std::string& network_name) {
@ -639,6 +636,16 @@ Network::Network(const std::string& name, const std::string& desc,
ignored_(false), type_(type), preference_(0) { 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. // Sets the addresses of this network. Returns true if the address set changed.
// Change detection is short circuited if the changed argument is true. // Change detection is short circuited if the changed argument is true.
bool Network::SetIPs(const std::vector<InterfaceAddress>& ips, bool changed) { bool Network::SetIPs(const std::vector<InterfaceAddress>& ips, bool changed) {
@ -662,52 +669,14 @@ bool Network::SetIPs(const std::vector<InterfaceAddress>& ips, bool changed) {
return changed; return changed;
} }
// Select the best IP address to use from this Network. // TODO(guoweis): will change the name to a more meaningful name as
IPAddress Network::GetBestIP() const { // this is not simply return the first address once the logic of ipv6
// address selection is complete.
IPAddress Network::ip() const {
if (ips_.size() == 0) { if (ips_.size() == 0) {
return IPAddress(); 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 } // namespace rtc

View File

@ -188,24 +188,19 @@ class Network {
std::string key() const { return key_; } std::string key() const { return key_; }
// Returns the Network's current idea of the 'best' IP it has. // Returns the Network's current idea of the 'best' IP it has.
// Or return an unset IP if this network has no active addresses. // 'Best' currently means the first one added.
// Here is the rule on how we mark the IPv6 address as ignorable for WebRTC. // 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.
// 1) return all global temporary dynamic and non-deprecrated ones. // 1) return all global temporary dynamic and non-deprecrated ones.
// 2) if #1 not available, return global ones. // 2) if #1 not available, return global dynamic ones.
// 3) if #2 not available, use ULA ipv6 as last resort. (ULA stands // 3) if #2 not available, return global ones.
// for unique local address, which is not route-able in open // 4) if #3 not available, use ULA ipv6 as last resort.
// 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 // Note that when not specifying any flag, it's treated as case global
// IPv6 address // dynamic IPv6 address
IPAddress GetBestIP() const; // 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;
// Adds an active IP address to this network. Does not check for duplicates. // Adds an active IP address to this network. Does not check for duplicates.
void AddIP(const InterfaceAddress& ip) { ips_.push_back(ip); } void AddIP(const InterfaceAddress& ip) { ips_.push_back(ip); }

View File

@ -114,7 +114,7 @@ TEST_F(NetworkTest, DISABLED_TestCreateNetworks) {
++it) { ++it) {
sockaddr_storage storage; sockaddr_storage storage;
memset(&storage, 0, sizeof(storage)); memset(&storage, 0, sizeof(storage));
IPAddress ip = (*it)->GetBestIP(); IPAddress ip = (*it)->ip();
SocketAddress bindaddress(ip, 0); SocketAddress bindaddress(ip, 0);
bindaddress.SetScopeID((*it)->scope_id()); bindaddress.SetScopeID((*it)->scope_id());
// TODO(thaloun): Use rtc::AsyncSocket once it supports IPv6. // TODO(thaloun): Use rtc::AsyncSocket once it supports IPv6.
@ -650,45 +650,4 @@ TEST_F(NetworkTest, TestMergeNetworkList) {
EXPECT_EQ(list2[0]->GetIPs()[1], ip2); 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 } // namespace rtc