15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/address_sorter_posix.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h" 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/socket/ssl_client_socket.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/socket/stream_socket.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/udp/datagram_client_socket.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to map destination address to source address. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<IPAddressNumber, IPAddressNumber> AddressMapping; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPAddressNumber ParseIP(const std::string& str) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber addr; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(ParseIPLiteralToNumber(str, &addr)); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return addr; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A mock socket which binds to source address according to AddressMapping. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestUDPClientSocket : public DatagramClientSocket { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit TestUDPClientSocket(const AddressMapping* mapping) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : mapping_(mapping), connected_(false) {} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestUDPClientSocket() {} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Read(IOBuffer*, int, const CompletionCallback&) OVERRIDE { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Write(IOBuffer*, int, const CompletionCallback&) OVERRIDE { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual int SetReceiveBufferSize(int32) OVERRIDE { 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return OK; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual int SetSendBufferSize(int32) OVERRIDE { 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return OK; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Close() OVERRIDE {} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!connected_) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNEXPECTED; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *address = local_endpoint_; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Connect(const IPEndPoint& remote) OVERRIDE { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connected_) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNEXPECTED; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressMapping::const_iterator it = mapping_->find(remote.address()); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == mapping_->end()) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_FAILED; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connected_ = true; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_endpoint_ = IPEndPoint(it->second, 39874 /* arbitrary port */); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual const BoundNetLog& NetLog() const OVERRIDE { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_log_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog net_log_; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AddressMapping* mapping_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool connected_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPEndPoint local_endpoint_; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestUDPClientSocket); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates TestUDPClientSockets and maintains an AddressMapping. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestSocketFactory : public ClientSocketFactory { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestSocketFactory() {} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestSocketFactory() {} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket( 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DatagramSocket::BindType, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RandIntCallback&, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog*, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetLog::Source&) OVERRIDE { 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<DatagramClientSocket>(new TestUDPClientSocket(&mapping_)); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual scoped_ptr<StreamSocket> CreateTransportClientSocket( 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AddressList&, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog*, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetLog::Source&) OVERRIDE { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<StreamSocket>(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual scoped_ptr<SSLClientSocket> CreateSSLClientSocket( 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<ClientSocketHandle>, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HostPortPair&, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLConfig&, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLClientSocketContext&) OVERRIDE { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<SSLClientSocket>(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ClearSSLSessionCache() OVERRIDE { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddMapping(const IPAddressNumber& dst, const IPAddressNumber& src) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mapping_[dst] = src; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressMapping mapping_; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestSocketFactory); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OnSortComplete(AddressList* result_buf, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AddressList& result) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(success); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result_buf = result; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(OK); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddressSorterPosixTest : public testing::Test { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressSorterPosixTest() : sorter_(&socket_factory_) {} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddMapping(const std::string& dst, const std::string& src) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_factory_.AddMapping(ParseIP(dst), ParseIP(src)); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressSorterPosix::SourceAddressInfo* GetSourceInfo( 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& addr) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber address = ParseIP(addr); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressSorterPosix::SourceAddressInfo* info = &sorter_.source_map_[address]; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info->scope == AddressSorterPosix::SCOPE_UNDEFINED) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorter_.FillPolicy(address, info); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return info; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that NULL-terminated |addresses| matches (-1)-terminated |order| 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after sorting. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Verify(const char* addresses[], const int order[]) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList list; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const char** addr = addresses; *addr != NULL; ++addr) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list.push_back(IPEndPoint(ParseIP(*addr), 80)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; order[i] >= 0; ++i) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_LT(order[i], static_cast<int>(list.size())); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList result; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorter_.Sort(list, base::Bind(&OnSortComplete, &result, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.callback())); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; (i < result.size()) || (order[i] >= 0); ++i) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPEndPoint expected = order[i] >= 0 ? list[order[i]] : IPEndPoint(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPEndPoint actual = i < result.size() ? result[i] : IPEndPoint(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(expected.address() == actual.address()) << 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Address out of order at position " << i << "\n" << 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " Actual: " << actual.ToStringWithoutPort() << "\n" << 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Expected: " << expected.ToStringWithoutPort(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestSocketFactory socket_factory_; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressSorterPosix sorter_; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 1: Avoid unusable destinations. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule1) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("10.0.0.231", "10.0.0.1"); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "::1", "10.0.0.231", "127.0.0.1", NULL }; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 1, -1 }; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 2: Prefer matching scope. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule2) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3002::1", "4000::10"); // matching global 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("ff32::1", "fe81::10"); // matching link-local 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("fec1::1", "fec1::10"); // matching node-local 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3002::2", "::1"); // global vs. link-local 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("fec1::2", "fe81::10"); // site-local vs. link-local 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("8.0.0.1", "169.254.0.10"); // global vs. link-local 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In all three cases, matching scope is preferred. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 1, 0, -1 }; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses1[] = { "3002::2", "3002::1", NULL }; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses1, order); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses2[] = { "fec1::2", "ff32::1", NULL }; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses2, order); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses3[] = { "8.0.0.1", "fec1::1", NULL }; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses3, order); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 3: Avoid deprecated addresses. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule3) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Matching scope. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3002::1", "4000::10"); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSourceInfo("4000::10")->deprecated = true; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3002::2", "4000::20"); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "3002::1", "3002::2", NULL }; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 1, 0, -1 }; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 4: Prefer home addresses. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule4) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3002::1", "4000::10"); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3002::2", "4000::20"); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSourceInfo("4000::20")->home = true; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "3002::1", "3002::2", NULL }; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 1, 0, -1 }; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 5: Prefer matching label. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule5) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("::1", "::1"); // matching loopback 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("::ffff:1234:1", "::ffff:1234:10"); // matching IPv4-mapped 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("2001::1", "::ffff:1234:10"); // Teredo vs. IPv4-mapped 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("2002::1", "2001::10"); // 6to4 vs. Teredo 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 1, 0, -1 }; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "2001::1", "::1", NULL }; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "2002::1", "::ffff:1234:1", NULL }; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 6: Prefer higher precedence. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule6) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("::1", "::1"); // loopback 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("ff32::1", "fe81::10"); // multicast 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("::ffff:1234:1", "::ffff:1234:10"); // IPv4-mapped 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("2001::1", "2001::10"); // Teredo 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "2001::1", "::ffff:1234:1", "ff32::1", "::1", 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL }; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 3, 2, 1, 0, -1 }; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 7: Prefer native transport. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule7) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3002::1", "4000::10"); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3002::2", "4000::20"); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSourceInfo("4000::20")->native = true; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "3002::1", "3002::2", NULL }; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 1, 0, -1 }; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 8: Prefer smaller scope. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule8) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Matching scope. Should precede the others by Rule 2. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("fe81::1", "fe81::10"); // link-local 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3000::1", "4000::10"); // global 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mismatched scope. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("ff32::1", "4000::10"); // link-local 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("ff35::1", "4000::10"); // site-local 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("ff38::1", "4000::10"); // org-local 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "ff38::1", "3000::1", "ff35::1", "ff32::1", 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "fe81::1", NULL }; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 4, 1, 3, 2, 0, -1 }; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 9: Use longest matching prefix. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule9) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("3000::1", "3000:ffff::10"); // 16 bit match 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSourceInfo("3000:ffff::10")->prefix_length = 16; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("4000::1", "4000::10"); // 123 bit match, limited to 15 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSourceInfo("4000::10")->prefix_length = 15; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("4002::1", "4000::10"); // 14 bit match 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("4080::1", "4000::10"); // 8 bit match 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "4080::1", "4002::1", "4000::1", "3000::1", 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL }; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 3, 2, 1, 0, -1 }; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Rule 10: Leave the order unchanged. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, Rule10) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("4000::1", "4000::10"); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("4000::2", "4000::10"); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("4000::3", "4000::10"); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "4000::1", "4000::2", "4000::3", NULL }; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 0, 1, 2, -1 }; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AddressSorterPosixTest, MultipleRules) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("::1", "::1"); // loopback 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("ff32::1", "fe81::10"); // link-local multicast 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("ff3e::1", "4000::10"); // global multicast 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("4000::1", "4000::10"); // global unicast 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMapping("ff32::2", "fe81::20"); // deprecated link-local multicast 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSourceInfo("fe81::20")->deprecated = true; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* addresses[] = { "ff3e::1", "ff32::2", "4000::1", "ff32::1", "::1", 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "8.0.0.1", NULL }; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int order[] = { 4, 3, 0, 2, 1, -1 }; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verify(addresses, order); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 328