xref: /aosp_15_r20/external/cronet/net/dns/address_sorter_posix_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/dns/address_sorter_posix.h"
6 
7 #include <memory>
8 #include <string>
9 #include <vector>
10 
11 #include "base/check_op.h"
12 #include "base/functional/bind.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/notreached.h"
15 #include "base/task/single_thread_task_runner.h"
16 #include "net/base/ip_address.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/network_change_notifier.h"
20 #include "net/base/test_completion_callback.h"
21 #include "net/log/net_log_with_source.h"
22 #include "net/socket/client_socket_factory.h"
23 #include "net/socket/datagram_client_socket.h"
24 #include "net/socket/socket_performance_watcher.h"
25 #include "net/socket/ssl_client_socket.h"
26 #include "net/socket/stream_socket.h"
27 #include "net/test/test_with_task_environment.h"
28 #include "net/traffic_annotation/network_traffic_annotation.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 
32 namespace net {
33 namespace {
34 
35 // Used to map destination address to source address.
36 typedef std::map<IPAddress, IPAddress> AddressMapping;
37 
ParseIP(const std::string & str)38 IPAddress ParseIP(const std::string& str) {
39   IPAddress addr;
40   CHECK(addr.AssignFromIPLiteral(str));
41   return addr;
42 }
43 
44 // A mock socket which binds to source address according to AddressMapping.
45 class TestUDPClientSocket : public DatagramClientSocket {
46  public:
47   enum class ConnectMode { kSynchronous, kAsynchronous, kAsynchronousManual };
TestUDPClientSocket(const AddressMapping * mapping,ConnectMode connect_mode)48   explicit TestUDPClientSocket(const AddressMapping* mapping,
49                                ConnectMode connect_mode)
50       : mapping_(mapping), connect_mode_(connect_mode) {}
51 
52   TestUDPClientSocket(const TestUDPClientSocket&) = delete;
53   TestUDPClientSocket& operator=(const TestUDPClientSocket&) = delete;
54 
55   ~TestUDPClientSocket() override = default;
56 
Read(IOBuffer *,int,CompletionOnceCallback)57   int Read(IOBuffer*, int, CompletionOnceCallback) override {
58     NOTIMPLEMENTED();
59     return OK;
60   }
Write(IOBuffer *,int,CompletionOnceCallback,const NetworkTrafficAnnotationTag & traffic_annotation)61   int Write(IOBuffer*,
62             int,
63             CompletionOnceCallback,
64             const NetworkTrafficAnnotationTag& traffic_annotation) override {
65     NOTIMPLEMENTED();
66     return OK;
67   }
SetReceiveBufferSize(int32_t)68   int SetReceiveBufferSize(int32_t) override { return OK; }
SetSendBufferSize(int32_t)69   int SetSendBufferSize(int32_t) override { return OK; }
SetDoNotFragment()70   int SetDoNotFragment() override { return OK; }
SetRecvTos()71   int SetRecvTos() override { return OK; }
SetTos(DiffServCodePoint dscp,EcnCodePoint ecn)72   int SetTos(DiffServCodePoint dscp, EcnCodePoint ecn) override { return OK; }
73 
Close()74   void Close() override {}
GetPeerAddress(IPEndPoint * address) const75   int GetPeerAddress(IPEndPoint* address) const override {
76     NOTIMPLEMENTED();
77     return OK;
78   }
GetLocalAddress(IPEndPoint * address) const79   int GetLocalAddress(IPEndPoint* address) const override {
80     if (!connected_)
81       return ERR_UNEXPECTED;
82     *address = local_endpoint_;
83     return OK;
84   }
UseNonBlockingIO()85   void UseNonBlockingIO() override {}
SetMulticastInterface(uint32_t interface_index)86   int SetMulticastInterface(uint32_t interface_index) override {
87     NOTIMPLEMENTED();
88     return ERR_NOT_IMPLEMENTED;
89   }
90 
ConnectUsingNetwork(handles::NetworkHandle network,const IPEndPoint & address)91   int ConnectUsingNetwork(handles::NetworkHandle network,
92                           const IPEndPoint& address) override {
93     NOTIMPLEMENTED();
94     return ERR_NOT_IMPLEMENTED;
95   }
96 
ConnectUsingDefaultNetwork(const IPEndPoint & address)97   int ConnectUsingDefaultNetwork(const IPEndPoint& address) override {
98     NOTIMPLEMENTED();
99     return ERR_NOT_IMPLEMENTED;
100   }
101 
ConnectAsync(const IPEndPoint & address,CompletionOnceCallback callback)102   int ConnectAsync(const IPEndPoint& address,
103                    CompletionOnceCallback callback) override {
104     DCHECK(callback);
105     int rv = Connect(address);
106     finish_connect_callback_ =
107         base::BindOnce(&TestUDPClientSocket::RunConnectCallback,
108                        weak_ptr_factory_.GetWeakPtr(), std::move(callback), rv);
109     if (connect_mode_ == ConnectMode::kAsynchronous) {
110       base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
111           FROM_HERE, std::move(finish_connect_callback_));
112       return ERR_IO_PENDING;
113     } else if (connect_mode_ == ConnectMode::kAsynchronousManual) {
114       return ERR_IO_PENDING;
115     }
116     return rv;
117   }
118 
ConnectUsingNetworkAsync(handles::NetworkHandle network,const IPEndPoint & address,CompletionOnceCallback callback)119   int ConnectUsingNetworkAsync(handles::NetworkHandle network,
120                                const IPEndPoint& address,
121                                CompletionOnceCallback callback) override {
122     NOTIMPLEMENTED();
123     return ERR_NOT_IMPLEMENTED;
124   }
125 
ConnectUsingDefaultNetworkAsync(const IPEndPoint & address,CompletionOnceCallback callback)126   int ConnectUsingDefaultNetworkAsync(
127       const IPEndPoint& address,
128       CompletionOnceCallback callback) override {
129     NOTIMPLEMENTED();
130     return ERR_NOT_IMPLEMENTED;
131   }
132 
GetBoundNetwork() const133   handles::NetworkHandle GetBoundNetwork() const override {
134     return handles::kInvalidNetworkHandle;
135   }
ApplySocketTag(const SocketTag & tag)136   void ApplySocketTag(const SocketTag& tag) override {}
SetMsgConfirm(bool confirm)137   void SetMsgConfirm(bool confirm) override {}
138 
Connect(const IPEndPoint & remote)139   int Connect(const IPEndPoint& remote) override {
140     if (connected_)
141       return ERR_UNEXPECTED;
142     auto it = mapping_->find(remote.address());
143     if (it == mapping_->end())
144       return ERR_FAILED;
145     connected_ = true;
146     local_endpoint_ = IPEndPoint(it->second, 39874 /* arbitrary port */);
147     return OK;
148   }
149 
NetLog() const150   const NetLogWithSource& NetLog() const override { return net_log_; }
151 
FinishConnect()152   void FinishConnect() { std::move(finish_connect_callback_).Run(); }
153 
GetLastTos() const154   DscpAndEcn GetLastTos() const override { return {DSCP_DEFAULT, ECN_DEFAULT}; }
155 
156  private:
RunConnectCallback(CompletionOnceCallback callback,int rv)157   void RunConnectCallback(CompletionOnceCallback callback, int rv) {
158     std::move(callback).Run(rv);
159   }
160   NetLogWithSource net_log_;
161   raw_ptr<const AddressMapping> mapping_;
162   bool connected_ = false;
163   IPEndPoint local_endpoint_;
164   ConnectMode connect_mode_;
165   base::OnceClosure finish_connect_callback_;
166 
167   base::WeakPtrFactory<TestUDPClientSocket> weak_ptr_factory_{this};
168 };
169 
170 // Creates TestUDPClientSockets and maintains an AddressMapping.
171 class TestSocketFactory : public ClientSocketFactory {
172  public:
173   TestSocketFactory() = default;
174 
175   TestSocketFactory(const TestSocketFactory&) = delete;
176   TestSocketFactory& operator=(const TestSocketFactory&) = delete;
177 
178   ~TestSocketFactory() override = default;
179 
CreateDatagramClientSocket(DatagramSocket::BindType,NetLog *,const NetLogSource &)180   std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
181       DatagramSocket::BindType,
182       NetLog*,
183       const NetLogSource&) override {
184     auto new_socket =
185         std::make_unique<TestUDPClientSocket>(&mapping_, connect_mode_);
186     if (socket_create_callback_) {
187       socket_create_callback_.Run(new_socket.get());
188     }
189     return new_socket;
190   }
CreateTransportClientSocket(const AddressList &,std::unique_ptr<SocketPerformanceWatcher>,net::NetworkQualityEstimator *,NetLog *,const NetLogSource &)191   std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
192       const AddressList&,
193       std::unique_ptr<SocketPerformanceWatcher>,
194       net::NetworkQualityEstimator*,
195       NetLog*,
196       const NetLogSource&) override {
197     NOTIMPLEMENTED();
198     return nullptr;
199   }
CreateSSLClientSocket(SSLClientContext *,std::unique_ptr<StreamSocket>,const HostPortPair &,const SSLConfig &)200   std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
201       SSLClientContext*,
202       std::unique_ptr<StreamSocket>,
203       const HostPortPair&,
204       const SSLConfig&) override {
205     NOTIMPLEMENTED();
206     return nullptr;
207   }
AddMapping(const IPAddress & dst,const IPAddress & src)208   void AddMapping(const IPAddress& dst, const IPAddress& src) {
209     mapping_[dst] = src;
210   }
SetConnectMode(TestUDPClientSocket::ConnectMode connect_mode)211   void SetConnectMode(TestUDPClientSocket::ConnectMode connect_mode) {
212     connect_mode_ = connect_mode;
213   }
SetSocketCreateCallback(base::RepeatingCallback<void (TestUDPClientSocket *)> socket_create_callback)214   void SetSocketCreateCallback(
215       base::RepeatingCallback<void(TestUDPClientSocket*)>
216           socket_create_callback) {
217     socket_create_callback_ = std::move(socket_create_callback);
218   }
219 
220  private:
221   AddressMapping mapping_;
222   TestUDPClientSocket::ConnectMode connect_mode_;
223   base::RepeatingCallback<void(TestUDPClientSocket*)> socket_create_callback_;
224 };
225 
OnSortComplete(bool & completed,std::vector<IPEndPoint> * sorted_buf,CompletionOnceCallback callback,bool success,std::vector<IPEndPoint> sorted)226 void OnSortComplete(bool& completed,
227                     std::vector<IPEndPoint>* sorted_buf,
228                     CompletionOnceCallback callback,
229                     bool success,
230                     std::vector<IPEndPoint> sorted) {
231   EXPECT_TRUE(success);
232   completed = true;
233   if (success)
234     *sorted_buf = std::move(sorted);
235   std::move(callback).Run(OK);
236 }
237 
238 }  // namespace
239 
240 // TaskEnvironment is required to register an IPAddressObserver from the
241 // constructor of AddressSorterPosix.
242 class AddressSorterPosixTest : public TestWithTaskEnvironment {
243  protected:
AddressSorterPosixTest()244   AddressSorterPosixTest()
245       : sorter_(std::make_unique<AddressSorterPosix>(&socket_factory_)) {}
246 
AddMapping(const std::string & dst,const std::string & src)247   void AddMapping(const std::string& dst, const std::string& src) {
248     socket_factory_.AddMapping(ParseIP(dst), ParseIP(src));
249   }
250 
SetSocketCreateCallback(base::RepeatingCallback<void (TestUDPClientSocket *)> socket_create_callback)251   void SetSocketCreateCallback(
252       base::RepeatingCallback<void(TestUDPClientSocket*)>
253           socket_create_callback) {
254     socket_factory_.SetSocketCreateCallback(std::move(socket_create_callback));
255   }
256 
SetConnectMode(TestUDPClientSocket::ConnectMode connect_mode)257   void SetConnectMode(TestUDPClientSocket::ConnectMode connect_mode) {
258     socket_factory_.SetConnectMode(connect_mode);
259   }
260 
GetSourceInfo(const std::string & addr)261   AddressSorterPosix::SourceAddressInfo* GetSourceInfo(
262       const std::string& addr) {
263     IPAddress address = ParseIP(addr);
264     AddressSorterPosix::SourceAddressInfo* info =
265         &sorter_->source_map_[address];
266     if (info->scope == AddressSorterPosix::SCOPE_UNDEFINED)
267       sorter_->FillPolicy(address, info);
268     return info;
269   }
270 
271   TestSocketFactory socket_factory_;
272   std::unique_ptr<AddressSorterPosix> sorter_;
273   bool completed_ = false;
274 
275  private:
276   friend class AddressSorterPosixSyncOrAsyncTest;
277 };
278 
279 // Parameterized subclass of AddressSorterPosixTest. Necessary because not every
280 // test needs to be parameterized.
281 class AddressSorterPosixSyncOrAsyncTest
282     : public AddressSorterPosixTest,
283       public testing::WithParamInterface<TestUDPClientSocket::ConnectMode> {
284  protected:
AddressSorterPosixSyncOrAsyncTest()285   AddressSorterPosixSyncOrAsyncTest() { SetConnectMode(GetParam()); }
286 
287   // Verify that NULL-terminated |addresses| matches (-1)-terminated |order|
288   // after sorting.
Verify(const char * const addresses[],const int order[])289   void Verify(const char* const addresses[], const int order[]) {
290     std::vector<IPEndPoint> endpoints;
291     for (const char* const* addr = addresses; *addr != nullptr; ++addr)
292       endpoints.emplace_back(ParseIP(*addr), 80);
293     for (size_t i = 0; order[i] >= 0; ++i)
294       CHECK_LT(order[i], static_cast<int>(endpoints.size()));
295 
296     std::vector<IPEndPoint> sorted;
297     TestCompletionCallback callback;
298     sorter_->Sort(endpoints,
299                   base::BindOnce(&OnSortComplete, std::ref(completed_), &sorted,
300                                  callback.callback()));
301     callback.WaitForResult();
302 
303     for (size_t i = 0; (i < sorted.size()) || (order[i] >= 0); ++i) {
304       IPEndPoint expected = order[i] >= 0 ? endpoints[order[i]] : IPEndPoint();
305       IPEndPoint actual = i < sorted.size() ? sorted[i] : IPEndPoint();
306       EXPECT_TRUE(expected == actual)
307           << "Endpoint out of order at position " << i << "\n"
308           << "  Actual: " << actual.ToString() << "\n"
309           << "Expected: " << expected.ToString();
310     }
311     EXPECT_TRUE(completed_);
312   }
313 };
314 
315 INSTANTIATE_TEST_SUITE_P(
316     AddressSorterPosix,
317     AddressSorterPosixSyncOrAsyncTest,
318     ::testing::Values(TestUDPClientSocket::ConnectMode::kSynchronous,
319                       TestUDPClientSocket::ConnectMode::kAsynchronous));
320 
321 // Rule 1: Avoid unusable destinations.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule1)322 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule1) {
323   AddMapping("10.0.0.231", "10.0.0.1");
324   const char* const addresses[] = {"::1", "10.0.0.231", "127.0.0.1", nullptr};
325   const int order[] = { 1, -1 };
326   Verify(addresses, order);
327 }
328 
329 // Rule 2: Prefer matching scope.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule2)330 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule2) {
331   AddMapping("3002::1", "4000::10");      // matching global
332   AddMapping("ff32::1", "fe81::10");      // matching link-local
333   AddMapping("fec1::1", "fec1::10");      // matching node-local
334   AddMapping("3002::2", "::1");           // global vs. link-local
335   AddMapping("fec1::2", "fe81::10");      // site-local vs. link-local
336   AddMapping("8.0.0.1", "169.254.0.10");  // global vs. link-local
337   // In all three cases, matching scope is preferred.
338   const int order[] = { 1, 0, -1 };
339   const char* const addresses1[] = {"3002::2", "3002::1", nullptr};
340   Verify(addresses1, order);
341   const char* const addresses2[] = {"fec1::2", "ff32::1", nullptr};
342   Verify(addresses2, order);
343   const char* const addresses3[] = {"8.0.0.1", "fec1::1", nullptr};
344   Verify(addresses3, order);
345 }
346 
347 // Rule 3: Avoid deprecated addresses.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule3)348 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule3) {
349   // Matching scope.
350   AddMapping("3002::1", "4000::10");
351   GetSourceInfo("4000::10")->deprecated = true;
352   AddMapping("3002::2", "4000::20");
353   const char* const addresses[] = {"3002::1", "3002::2", nullptr};
354   const int order[] = { 1, 0, -1 };
355   Verify(addresses, order);
356 }
357 
358 // Rule 4: Prefer home addresses.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule4)359 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule4) {
360   AddMapping("3002::1", "4000::10");
361   AddMapping("3002::2", "4000::20");
362   GetSourceInfo("4000::20")->home = true;
363   const char* const addresses[] = {"3002::1", "3002::2", nullptr};
364   const int order[] = { 1, 0, -1 };
365   Verify(addresses, order);
366 }
367 
368 // Rule 5: Prefer matching label.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule5)369 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule5) {
370   AddMapping("::1", "::1");                       // matching loopback
371   AddMapping("::ffff:1234:1", "::ffff:1234:10");  // matching IPv4-mapped
372   AddMapping("2001::1", "::ffff:1234:10");        // Teredo vs. IPv4-mapped
373   AddMapping("2002::1", "2001::10");              // 6to4 vs. Teredo
374   const int order[] = { 1, 0, -1 };
375   {
376     const char* const addresses[] = {"2001::1", "::1", nullptr};
377     Verify(addresses, order);
378   }
379   {
380     const char* const addresses[] = {"2002::1", "::ffff:1234:1", nullptr};
381     Verify(addresses, order);
382   }
383 }
384 
385 // Rule 6: Prefer higher precedence.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule6)386 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule6) {
387   AddMapping("::1", "::1");                       // loopback
388   AddMapping("ff32::1", "fe81::10");              // multicast
389   AddMapping("::ffff:1234:1", "::ffff:1234:10");  // IPv4-mapped
390   AddMapping("2001::1", "2001::10");              // Teredo
391   const char* const addresses[] = {"2001::1", "::ffff:1234:1", "ff32::1", "::1",
392                                    nullptr};
393   const int order[] = { 3, 2, 1, 0, -1 };
394   Verify(addresses, order);
395 }
396 
397 // Rule 7: Prefer native transport.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule7)398 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule7) {
399   AddMapping("3002::1", "4000::10");
400   AddMapping("3002::2", "4000::20");
401   GetSourceInfo("4000::20")->native = true;
402   const char* const addresses[] = {"3002::1", "3002::2", nullptr};
403   const int order[] = { 1, 0, -1 };
404   Verify(addresses, order);
405 }
406 
407 // Rule 8: Prefer smaller scope.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule8)408 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule8) {
409   // Matching scope. Should precede the others by Rule 2.
410   AddMapping("fe81::1", "fe81::10");  // link-local
411   AddMapping("3000::1", "4000::10");  // global
412   // Mismatched scope.
413   AddMapping("ff32::1", "4000::10");  // link-local
414   AddMapping("ff35::1", "4000::10");  // site-local
415   AddMapping("ff38::1", "4000::10");  // org-local
416   const char* const addresses[] = {"ff38::1", "3000::1", "ff35::1",
417                                    "ff32::1", "fe81::1", nullptr};
418   const int order[] = { 4, 1, 3, 2, 0, -1 };
419   Verify(addresses, order);
420 }
421 
422 // Rule 9: Use longest matching prefix.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule9)423 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule9) {
424   AddMapping("3000::1", "3000:ffff::10");  // 16 bit match
425   GetSourceInfo("3000:ffff::10")->prefix_length = 16;
426   AddMapping("4000::1", "4000::10");       // 123 bit match, limited to 15
427   GetSourceInfo("4000::10")->prefix_length = 15;
428   AddMapping("4002::1", "4000::10");       // 14 bit match
429   AddMapping("4080::1", "4000::10");       // 8 bit match
430   const char* const addresses[] = {"4080::1", "4002::1", "4000::1", "3000::1",
431                                    nullptr};
432   const int order[] = { 3, 2, 1, 0, -1 };
433   Verify(addresses, order);
434 }
435 
436 // Rule 10: Leave the order unchanged.
TEST_P(AddressSorterPosixSyncOrAsyncTest,Rule10)437 TEST_P(AddressSorterPosixSyncOrAsyncTest, Rule10) {
438   AddMapping("4000::1", "4000::10");
439   AddMapping("4000::2", "4000::10");
440   AddMapping("4000::3", "4000::10");
441   const char* const addresses[] = {"4000::1", "4000::2", "4000::3", nullptr};
442   const int order[] = { 0, 1, 2, -1 };
443   Verify(addresses, order);
444 }
445 
TEST_P(AddressSorterPosixSyncOrAsyncTest,MultipleRules)446 TEST_P(AddressSorterPosixSyncOrAsyncTest, MultipleRules) {
447   AddMapping("::1", "::1");           // loopback
448   AddMapping("ff32::1", "fe81::10");  // link-local multicast
449   AddMapping("ff3e::1", "4000::10");  // global multicast
450   AddMapping("4000::1", "4000::10");  // global unicast
451   AddMapping("ff32::2", "fe81::20");  // deprecated link-local multicast
452   GetSourceInfo("fe81::20")->deprecated = true;
453   const char* const addresses[] = {"ff3e::1", "ff32::2", "4000::1", "ff32::1",
454                                    "::1",     "8.0.0.1", nullptr};
455   const int order[] = { 4, 3, 0, 2, 1, -1 };
456   Verify(addresses, order);
457 }
458 
TEST_P(AddressSorterPosixSyncOrAsyncTest,InputPortsAreMaintained)459 TEST_P(AddressSorterPosixSyncOrAsyncTest, InputPortsAreMaintained) {
460   AddMapping("::1", "::1");
461   AddMapping("::2", "::2");
462   AddMapping("::3", "::3");
463 
464   IPEndPoint endpoint1(ParseIP("::1"), /*port=*/111);
465   IPEndPoint endpoint2(ParseIP("::2"), /*port=*/222);
466   IPEndPoint endpoint3(ParseIP("::3"), /*port=*/333);
467 
468   std::vector<IPEndPoint> input = {endpoint1, endpoint2, endpoint3};
469   std::vector<IPEndPoint> sorted;
470   TestCompletionCallback callback;
471   sorter_->Sort(input, base::BindOnce(&OnSortComplete, std::ref(completed_),
472                                       &sorted, callback.callback()));
473   callback.WaitForResult();
474 
475   EXPECT_THAT(sorted, testing::ElementsAre(endpoint1, endpoint2, endpoint3));
476 }
477 
TEST_P(AddressSorterPosixSyncOrAsyncTest,AddressSorterPosixDestroyed)478 TEST_P(AddressSorterPosixSyncOrAsyncTest, AddressSorterPosixDestroyed) {
479   AddMapping("::1", "::1");
480   AddMapping("::2", "::2");
481   AddMapping("::3", "::3");
482 
483   IPEndPoint endpoint1(ParseIP("::1"), /*port=*/111);
484   IPEndPoint endpoint2(ParseIP("::2"), /*port=*/222);
485   IPEndPoint endpoint3(ParseIP("::3"), /*port=*/333);
486 
487   std::vector<IPEndPoint> input = {endpoint1, endpoint2, endpoint3};
488   std::vector<IPEndPoint> sorted;
489   TestCompletionCallback callback;
490   sorter_->Sort(input, base::BindOnce(&OnSortComplete, std::ref(completed_),
491                                       &sorted, callback.callback()));
492   sorter_.reset();
493   base::RunLoop().RunUntilIdle();
494 
495   TestUDPClientSocket::ConnectMode connect_mode = GetParam();
496   if (connect_mode == TestUDPClientSocket::ConnectMode::kAsynchronous) {
497     EXPECT_FALSE(completed_);
498   } else {
499     EXPECT_TRUE(completed_);
500   }
501 }
502 
TEST_F(AddressSorterPosixTest,RandomAsyncSocketOrder)503 TEST_F(AddressSorterPosixTest, RandomAsyncSocketOrder) {
504   SetConnectMode(TestUDPClientSocket::ConnectMode::kAsynchronousManual);
505   std::vector<TestUDPClientSocket*> created_sockets;
506   SetSocketCreateCallback(base::BindRepeating(
507       [](std::vector<TestUDPClientSocket*>& created_sockets,
508          TestUDPClientSocket* socket) { created_sockets.push_back(socket); },
509       std::ref(created_sockets)));
510 
511   AddMapping("::1", "::1");
512   AddMapping("::2", "::2");
513   AddMapping("::3", "::3");
514 
515   IPEndPoint endpoint1(ParseIP("::1"), /*port=*/111);
516   IPEndPoint endpoint2(ParseIP("::2"), /*port=*/222);
517   IPEndPoint endpoint3(ParseIP("::3"), /*port=*/333);
518 
519   std::vector<IPEndPoint> input = {endpoint1, endpoint2, endpoint3};
520   std::vector<IPEndPoint> sorted;
521   TestCompletionCallback callback;
522   sorter_->Sort(input, base::BindOnce(&OnSortComplete, std::ref(completed_),
523                                       &sorted, callback.callback()));
524 
525   ASSERT_EQ(created_sockets.size(), 3u);
526   created_sockets[1]->FinishConnect();
527   created_sockets[2]->FinishConnect();
528   created_sockets[0]->FinishConnect();
529 
530   base::RunLoop().RunUntilIdle();
531   EXPECT_TRUE(completed_);
532 }
533 
534 // Regression test for https://crbug.com/1374387
TEST_F(AddressSorterPosixTest,IPAddressChangedSort)535 TEST_F(AddressSorterPosixTest, IPAddressChangedSort) {
536   SetConnectMode(TestUDPClientSocket::ConnectMode::kAsynchronousManual);
537   std::vector<TestUDPClientSocket*> created_sockets;
538   SetSocketCreateCallback(base::BindRepeating(
539       [](std::vector<TestUDPClientSocket*>& created_sockets,
540          TestUDPClientSocket* socket) { created_sockets.push_back(socket); },
541       std::ref(created_sockets)));
542 
543   AddMapping("::1", "::1");
544   AddMapping("::2", "::2");
545   AddMapping("::3", "::3");
546 
547   IPEndPoint endpoint1(ParseIP("::1"), /*port=*/111);
548   IPEndPoint endpoint2(ParseIP("::2"), /*port=*/222);
549   IPEndPoint endpoint3(ParseIP("::3"), /*port=*/333);
550 
551   std::vector<IPEndPoint> input = {endpoint1, endpoint2, endpoint3};
552   std::vector<IPEndPoint> sorted;
553   TestCompletionCallback callback;
554   sorter_->Sort(input, base::BindOnce(&OnSortComplete, std::ref(completed_),
555                                       &sorted, callback.callback()));
556 
557   ASSERT_EQ(created_sockets.size(), 3u);
558   created_sockets[0]->FinishConnect();
559   // Trigger OnIPAddressChanged() to reset `source_map_`
560   NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
561   base::RunLoop().RunUntilIdle();
562   created_sockets[1]->FinishConnect();
563   created_sockets[2]->FinishConnect();
564 
565   base::RunLoop().RunUntilIdle();
566   EXPECT_TRUE(completed_);
567 }
568 
569 }  // namespace net
570