address_sorter_posix_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/dns/address_sorter_posix.h"
  5. #include <memory>
  6. #include <string>
  7. #include <vector>
  8. #include "base/bind.h"
  9. #include "base/check_op.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/notreached.h"
  12. #include "net/base/ip_address.h"
  13. #include "net/base/ip_endpoint.h"
  14. #include "net/base/net_errors.h"
  15. #include "net/base/test_completion_callback.h"
  16. #include "net/log/net_log_with_source.h"
  17. #include "net/socket/client_socket_factory.h"
  18. #include "net/socket/datagram_client_socket.h"
  19. #include "net/socket/socket_performance_watcher.h"
  20. #include "net/socket/ssl_client_socket.h"
  21. #include "net/socket/stream_socket.h"
  22. #include "net/test/test_with_task_environment.h"
  23. #include "net/traffic_annotation/network_traffic_annotation.h"
  24. #include "testing/gmock/include/gmock/gmock.h"
  25. #include "testing/gtest/include/gtest/gtest.h"
  26. namespace net {
  27. namespace {
  28. // Used to map destination address to source address.
  29. typedef std::map<IPAddress, IPAddress> AddressMapping;
  30. IPAddress ParseIP(const std::string& str) {
  31. IPAddress addr;
  32. CHECK(addr.AssignFromIPLiteral(str));
  33. return addr;
  34. }
  35. // A mock socket which binds to source address according to AddressMapping.
  36. class TestUDPClientSocket : public DatagramClientSocket {
  37. public:
  38. explicit TestUDPClientSocket(const AddressMapping* mapping)
  39. : mapping_(mapping) {}
  40. TestUDPClientSocket(const TestUDPClientSocket&) = delete;
  41. TestUDPClientSocket& operator=(const TestUDPClientSocket&) = delete;
  42. ~TestUDPClientSocket() override = default;
  43. int Read(IOBuffer*, int, CompletionOnceCallback) override {
  44. NOTIMPLEMENTED();
  45. return OK;
  46. }
  47. int Write(IOBuffer*,
  48. int,
  49. CompletionOnceCallback,
  50. const NetworkTrafficAnnotationTag& traffic_annotation) override {
  51. NOTIMPLEMENTED();
  52. return OK;
  53. }
  54. int SetReceiveBufferSize(int32_t) override { return OK; }
  55. int SetSendBufferSize(int32_t) override { return OK; }
  56. int SetDoNotFragment() override { return OK; }
  57. void Close() override {}
  58. int GetPeerAddress(IPEndPoint* address) const override {
  59. NOTIMPLEMENTED();
  60. return OK;
  61. }
  62. int GetLocalAddress(IPEndPoint* address) const override {
  63. if (!connected_)
  64. return ERR_UNEXPECTED;
  65. *address = local_endpoint_;
  66. return OK;
  67. }
  68. void UseNonBlockingIO() override {}
  69. int SetMulticastInterface(uint32_t interface_index) override {
  70. NOTIMPLEMENTED();
  71. return ERR_NOT_IMPLEMENTED;
  72. }
  73. int ConnectUsingNetwork(handles::NetworkHandle network,
  74. const IPEndPoint& address) override {
  75. NOTIMPLEMENTED();
  76. return ERR_NOT_IMPLEMENTED;
  77. }
  78. int ConnectUsingDefaultNetwork(const IPEndPoint& address) override {
  79. NOTIMPLEMENTED();
  80. return ERR_NOT_IMPLEMENTED;
  81. }
  82. handles::NetworkHandle GetBoundNetwork() const override {
  83. return handles::kInvalidNetworkHandle;
  84. }
  85. void ApplySocketTag(const SocketTag& tag) override {}
  86. void SetMsgConfirm(bool confirm) override {}
  87. int Connect(const IPEndPoint& remote) override {
  88. if (connected_)
  89. return ERR_UNEXPECTED;
  90. auto it = mapping_->find(remote.address());
  91. if (it == mapping_->end())
  92. return ERR_FAILED;
  93. connected_ = true;
  94. local_endpoint_ = IPEndPoint(it->second, 39874 /* arbitrary port */);
  95. return OK;
  96. }
  97. const NetLogWithSource& NetLog() const override { return net_log_; }
  98. private:
  99. NetLogWithSource net_log_;
  100. raw_ptr<const AddressMapping> mapping_;
  101. bool connected_ = false;
  102. IPEndPoint local_endpoint_;
  103. };
  104. // Creates TestUDPClientSockets and maintains an AddressMapping.
  105. class TestSocketFactory : public ClientSocketFactory {
  106. public:
  107. TestSocketFactory() = default;
  108. TestSocketFactory(const TestSocketFactory&) = delete;
  109. TestSocketFactory& operator=(const TestSocketFactory&) = delete;
  110. ~TestSocketFactory() override = default;
  111. std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
  112. DatagramSocket::BindType,
  113. NetLog*,
  114. const NetLogSource&) override {
  115. return std::make_unique<TestUDPClientSocket>(&mapping_);
  116. }
  117. std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
  118. const AddressList&,
  119. std::unique_ptr<SocketPerformanceWatcher>,
  120. net::NetworkQualityEstimator*,
  121. NetLog*,
  122. const NetLogSource&) override {
  123. NOTIMPLEMENTED();
  124. return nullptr;
  125. }
  126. std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
  127. SSLClientContext*,
  128. std::unique_ptr<StreamSocket>,
  129. const HostPortPair&,
  130. const SSLConfig&) override {
  131. NOTIMPLEMENTED();
  132. return nullptr;
  133. }
  134. void AddMapping(const IPAddress& dst, const IPAddress& src) {
  135. mapping_[dst] = src;
  136. }
  137. private:
  138. AddressMapping mapping_;
  139. };
  140. void OnSortComplete(std::vector<IPEndPoint>* sorted_buf,
  141. CompletionOnceCallback callback,
  142. bool success,
  143. std::vector<IPEndPoint> sorted) {
  144. EXPECT_TRUE(success);
  145. if (success)
  146. *sorted_buf = std::move(sorted);
  147. std::move(callback).Run(OK);
  148. }
  149. } // namespace
  150. // TaskEnvironment is required to register an IPAddressObserver from the
  151. // constructor of AddressSorterPosix.
  152. class AddressSorterPosixTest : public TestWithTaskEnvironment {
  153. protected:
  154. AddressSorterPosixTest() : sorter_(&socket_factory_) {}
  155. void AddMapping(const std::string& dst, const std::string& src) {
  156. socket_factory_.AddMapping(ParseIP(dst), ParseIP(src));
  157. }
  158. AddressSorterPosix::SourceAddressInfo* GetSourceInfo(
  159. const std::string& addr) {
  160. IPAddress address = ParseIP(addr);
  161. AddressSorterPosix::SourceAddressInfo* info = &sorter_.source_map_[address];
  162. if (info->scope == AddressSorterPosix::SCOPE_UNDEFINED)
  163. sorter_.FillPolicy(address, info);
  164. return info;
  165. }
  166. // Verify that NULL-terminated |addresses| matches (-1)-terminated |order|
  167. // after sorting.
  168. void Verify(const char* const addresses[], const int order[]) {
  169. std::vector<IPEndPoint> endpoints;
  170. for (const char* const* addr = addresses; *addr != nullptr; ++addr)
  171. endpoints.emplace_back(ParseIP(*addr), 80);
  172. for (size_t i = 0; order[i] >= 0; ++i)
  173. CHECK_LT(order[i], static_cast<int>(endpoints.size()));
  174. std::vector<IPEndPoint> sorted;
  175. TestCompletionCallback callback;
  176. sorter_.Sort(endpoints,
  177. base::BindOnce(&OnSortComplete, &sorted, callback.callback()));
  178. callback.WaitForResult();
  179. for (size_t i = 0; (i < sorted.size()) || (order[i] >= 0); ++i) {
  180. IPEndPoint expected = order[i] >= 0 ? endpoints[order[i]] : IPEndPoint();
  181. IPEndPoint actual = i < sorted.size() ? sorted[i] : IPEndPoint();
  182. EXPECT_TRUE(expected == actual)
  183. << "Endpoint out of order at position " << i << "\n"
  184. << " Actual: " << actual.ToString() << "\n"
  185. << "Expected: " << expected.ToString();
  186. }
  187. }
  188. TestSocketFactory socket_factory_;
  189. AddressSorterPosix sorter_;
  190. };
  191. // Rule 1: Avoid unusable destinations.
  192. TEST_F(AddressSorterPosixTest, Rule1) {
  193. AddMapping("10.0.0.231", "10.0.0.1");
  194. const char* const addresses[] = {"::1", "10.0.0.231", "127.0.0.1", nullptr};
  195. const int order[] = { 1, -1 };
  196. Verify(addresses, order);
  197. }
  198. // Rule 2: Prefer matching scope.
  199. TEST_F(AddressSorterPosixTest, Rule2) {
  200. AddMapping("3002::1", "4000::10"); // matching global
  201. AddMapping("ff32::1", "fe81::10"); // matching link-local
  202. AddMapping("fec1::1", "fec1::10"); // matching node-local
  203. AddMapping("3002::2", "::1"); // global vs. link-local
  204. AddMapping("fec1::2", "fe81::10"); // site-local vs. link-local
  205. AddMapping("8.0.0.1", "169.254.0.10"); // global vs. link-local
  206. // In all three cases, matching scope is preferred.
  207. const int order[] = { 1, 0, -1 };
  208. const char* const addresses1[] = {"3002::2", "3002::1", nullptr};
  209. Verify(addresses1, order);
  210. const char* const addresses2[] = {"fec1::2", "ff32::1", nullptr};
  211. Verify(addresses2, order);
  212. const char* const addresses3[] = {"8.0.0.1", "fec1::1", nullptr};
  213. Verify(addresses3, order);
  214. }
  215. // Rule 3: Avoid deprecated addresses.
  216. TEST_F(AddressSorterPosixTest, Rule3) {
  217. // Matching scope.
  218. AddMapping("3002::1", "4000::10");
  219. GetSourceInfo("4000::10")->deprecated = true;
  220. AddMapping("3002::2", "4000::20");
  221. const char* const addresses[] = {"3002::1", "3002::2", nullptr};
  222. const int order[] = { 1, 0, -1 };
  223. Verify(addresses, order);
  224. }
  225. // Rule 4: Prefer home addresses.
  226. TEST_F(AddressSorterPosixTest, Rule4) {
  227. AddMapping("3002::1", "4000::10");
  228. AddMapping("3002::2", "4000::20");
  229. GetSourceInfo("4000::20")->home = true;
  230. const char* const addresses[] = {"3002::1", "3002::2", nullptr};
  231. const int order[] = { 1, 0, -1 };
  232. Verify(addresses, order);
  233. }
  234. // Rule 5: Prefer matching label.
  235. TEST_F(AddressSorterPosixTest, Rule5) {
  236. AddMapping("::1", "::1"); // matching loopback
  237. AddMapping("::ffff:1234:1", "::ffff:1234:10"); // matching IPv4-mapped
  238. AddMapping("2001::1", "::ffff:1234:10"); // Teredo vs. IPv4-mapped
  239. AddMapping("2002::1", "2001::10"); // 6to4 vs. Teredo
  240. const int order[] = { 1, 0, -1 };
  241. {
  242. const char* const addresses[] = {"2001::1", "::1", nullptr};
  243. Verify(addresses, order);
  244. }
  245. {
  246. const char* const addresses[] = {"2002::1", "::ffff:1234:1", nullptr};
  247. Verify(addresses, order);
  248. }
  249. }
  250. // Rule 6: Prefer higher precedence.
  251. TEST_F(AddressSorterPosixTest, Rule6) {
  252. AddMapping("::1", "::1"); // loopback
  253. AddMapping("ff32::1", "fe81::10"); // multicast
  254. AddMapping("::ffff:1234:1", "::ffff:1234:10"); // IPv4-mapped
  255. AddMapping("2001::1", "2001::10"); // Teredo
  256. const char* const addresses[] = {"2001::1", "::ffff:1234:1", "ff32::1", "::1",
  257. nullptr};
  258. const int order[] = { 3, 2, 1, 0, -1 };
  259. Verify(addresses, order);
  260. }
  261. // Rule 7: Prefer native transport.
  262. TEST_F(AddressSorterPosixTest, Rule7) {
  263. AddMapping("3002::1", "4000::10");
  264. AddMapping("3002::2", "4000::20");
  265. GetSourceInfo("4000::20")->native = true;
  266. const char* const addresses[] = {"3002::1", "3002::2", nullptr};
  267. const int order[] = { 1, 0, -1 };
  268. Verify(addresses, order);
  269. }
  270. // Rule 8: Prefer smaller scope.
  271. TEST_F(AddressSorterPosixTest, Rule8) {
  272. // Matching scope. Should precede the others by Rule 2.
  273. AddMapping("fe81::1", "fe81::10"); // link-local
  274. AddMapping("3000::1", "4000::10"); // global
  275. // Mismatched scope.
  276. AddMapping("ff32::1", "4000::10"); // link-local
  277. AddMapping("ff35::1", "4000::10"); // site-local
  278. AddMapping("ff38::1", "4000::10"); // org-local
  279. const char* const addresses[] = {"ff38::1", "3000::1", "ff35::1",
  280. "ff32::1", "fe81::1", nullptr};
  281. const int order[] = { 4, 1, 3, 2, 0, -1 };
  282. Verify(addresses, order);
  283. }
  284. // Rule 9: Use longest matching prefix.
  285. TEST_F(AddressSorterPosixTest, Rule9) {
  286. AddMapping("3000::1", "3000:ffff::10"); // 16 bit match
  287. GetSourceInfo("3000:ffff::10")->prefix_length = 16;
  288. AddMapping("4000::1", "4000::10"); // 123 bit match, limited to 15
  289. GetSourceInfo("4000::10")->prefix_length = 15;
  290. AddMapping("4002::1", "4000::10"); // 14 bit match
  291. AddMapping("4080::1", "4000::10"); // 8 bit match
  292. const char* const addresses[] = {"4080::1", "4002::1", "4000::1", "3000::1",
  293. nullptr};
  294. const int order[] = { 3, 2, 1, 0, -1 };
  295. Verify(addresses, order);
  296. }
  297. // Rule 10: Leave the order unchanged.
  298. TEST_F(AddressSorterPosixTest, Rule10) {
  299. AddMapping("4000::1", "4000::10");
  300. AddMapping("4000::2", "4000::10");
  301. AddMapping("4000::3", "4000::10");
  302. const char* const addresses[] = {"4000::1", "4000::2", "4000::3", nullptr};
  303. const int order[] = { 0, 1, 2, -1 };
  304. Verify(addresses, order);
  305. }
  306. TEST_F(AddressSorterPosixTest, MultipleRules) {
  307. AddMapping("::1", "::1"); // loopback
  308. AddMapping("ff32::1", "fe81::10"); // link-local multicast
  309. AddMapping("ff3e::1", "4000::10"); // global multicast
  310. AddMapping("4000::1", "4000::10"); // global unicast
  311. AddMapping("ff32::2", "fe81::20"); // deprecated link-local multicast
  312. GetSourceInfo("fe81::20")->deprecated = true;
  313. const char* const addresses[] = {"ff3e::1", "ff32::2", "4000::1", "ff32::1",
  314. "::1", "8.0.0.1", nullptr};
  315. const int order[] = { 4, 3, 0, 2, 1, -1 };
  316. Verify(addresses, order);
  317. }
  318. TEST_F(AddressSorterPosixTest, InputPortsAreMaintained) {
  319. AddMapping("::1", "::1");
  320. AddMapping("::2", "::2");
  321. AddMapping("::3", "::3");
  322. IPEndPoint endpoint1(ParseIP("::1"), /*port=*/111);
  323. IPEndPoint endpoint2(ParseIP("::2"), /*port=*/222);
  324. IPEndPoint endpoint3(ParseIP("::3"), /*port=*/333);
  325. std::vector<IPEndPoint> input = {endpoint1, endpoint2, endpoint3};
  326. std::vector<IPEndPoint> sorted;
  327. TestCompletionCallback callback;
  328. sorter_.Sort(input,
  329. base::BindOnce(&OnSortComplete, &sorted, callback.callback()));
  330. callback.WaitForResult();
  331. EXPECT_THAT(sorted, testing::ElementsAre(endpoint1, endpoint2, endpoint3));
  332. }
  333. } // namespace net