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