1 //
2 // connect.cpp
3 // ~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 // Disable autolinking for unit tests.
12 #if !defined(BOOST_ALL_NO_LIB)
13 #define BOOST_ALL_NO_LIB 1
14 #endif // !defined(BOOST_ALL_NO_LIB)
15 
16 // Test that header file is self-contained.
17 #include <boost/asio/connect.hpp>
18 
19 #include <vector>
20 #include <boost/asio/detail/thread.hpp>
21 #include <boost/asio/ip/tcp.hpp>
22 
23 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
24 # include <boost/bind/bind.hpp>
25 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
26 # include <functional>
27 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
28 
29 #include "unit_test.hpp"
30 
31 #if defined(BOOST_ASIO_HAS_BOOST_BIND)
32 namespace bindns = boost;
33 #else // defined(BOOST_ASIO_HAS_BOOST_BIND)
34 namespace bindns = std;
35 #endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
36 using bindns::placeholders::_1;
37 using bindns::placeholders::_2;
38 
39 class connection_sink
40 {
41 public:
connection_sink()42   connection_sink()
43     : acceptor_(io_context_,
44         boost::asio::ip::tcp::endpoint(
45           boost::asio::ip::address_v4::loopback(), 0)),
46       target_endpoint_(acceptor_.local_endpoint()),
47       socket_(io_context_),
48       thread_(bindns::bind(&connection_sink::run, this))
49   {
50   }
51 
~connection_sink()52   ~connection_sink()
53   {
54     io_context_.stop();
55     thread_.join();
56   }
57 
target_endpoint()58   boost::asio::ip::tcp::endpoint target_endpoint()
59   {
60     return target_endpoint_;
61   }
62 
63 private:
run()64   void run()
65   {
66     io_context_.run();
67   }
68 
handle_accept()69   void handle_accept()
70   {
71     socket_.close();
72     acceptor_.async_accept(socket_,
73         bindns::bind(&connection_sink::handle_accept, this));
74   }
75 
76   boost::asio::io_context io_context_;
77   boost::asio::ip::tcp::acceptor acceptor_;
78   boost::asio::ip::tcp::endpoint target_endpoint_;
79   boost::asio::ip::tcp::socket socket_;
80   boost::asio::detail::thread thread_;
81 };
82 
true_cond_1(const boost::system::error_code &,const boost::asio::ip::tcp::endpoint &)83 bool true_cond_1(const boost::system::error_code& /*ec*/,
84     const boost::asio::ip::tcp::endpoint& /*endpoint*/)
85 {
86   return true;
87 }
88 
89 struct true_cond_2
90 {
91   template <typename Endpoint>
operator ()true_cond_292   bool operator()(const boost::system::error_code& /*ec*/,
93       const Endpoint& /*endpoint*/)
94   {
95     return true;
96   }
97 };
98 
legacy_true_cond_1(const boost::system::error_code &,std::vector<boost::asio::ip::tcp::endpoint>::const_iterator next)99 std::vector<boost::asio::ip::tcp::endpoint>::const_iterator legacy_true_cond_1(
100     const boost::system::error_code& /*ec*/,
101     std::vector<boost::asio::ip::tcp::endpoint>::const_iterator next)
102 {
103   return next;
104 }
105 
106 struct legacy_true_cond_2
107 {
108   template <typename Iterator>
operator ()legacy_true_cond_2109   Iterator operator()(const boost::system::error_code& /*ec*/, Iterator next)
110   {
111     return next;
112   }
113 };
114 
false_cond(const boost::system::error_code &,const boost::asio::ip::tcp::endpoint &)115 bool false_cond(const boost::system::error_code& /*ec*/,
116     const boost::asio::ip::tcp::endpoint& /*endpoint*/)
117 {
118   return false;
119 }
120 
range_handler(const boost::system::error_code & ec,const boost::asio::ip::tcp::endpoint & endpoint,boost::system::error_code * out_ec,boost::asio::ip::tcp::endpoint * out_endpoint)121 void range_handler(const boost::system::error_code& ec,
122     const boost::asio::ip::tcp::endpoint& endpoint,
123     boost::system::error_code* out_ec,
124     boost::asio::ip::tcp::endpoint* out_endpoint)
125 {
126   *out_ec = ec;
127   *out_endpoint = endpoint;
128 }
129 
iter_handler(const boost::system::error_code & ec,std::vector<boost::asio::ip::tcp::endpoint>::const_iterator iter,boost::system::error_code * out_ec,std::vector<boost::asio::ip::tcp::endpoint>::const_iterator * out_iter)130 void iter_handler(const boost::system::error_code& ec,
131     std::vector<boost::asio::ip::tcp::endpoint>::const_iterator iter,
132     boost::system::error_code* out_ec,
133     std::vector<boost::asio::ip::tcp::endpoint>::const_iterator* out_iter)
134 {
135   *out_ec = ec;
136   *out_iter = iter;
137 }
138 
test_connect_range()139 void test_connect_range()
140 {
141   connection_sink sink;
142   boost::asio::io_context io_context;
143   boost::asio::ip::tcp::socket socket(io_context);
144   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
145   boost::asio::ip::tcp::endpoint result;
146 
147   try
148   {
149     result = boost::asio::connect(socket, endpoints);
150     BOOST_ASIO_CHECK(false);
151   }
152   catch (boost::system::system_error& e)
153   {
154     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
155   }
156 
157   endpoints.push_back(sink.target_endpoint());
158 
159   result = boost::asio::connect(socket, endpoints);
160   BOOST_ASIO_CHECK(result == endpoints[0]);
161 
162   endpoints.push_back(sink.target_endpoint());
163 
164   result = boost::asio::connect(socket, endpoints);
165   BOOST_ASIO_CHECK(result == endpoints[0]);
166 
167   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
168 
169   result = boost::asio::connect(socket, endpoints);
170   BOOST_ASIO_CHECK(result == endpoints[1]);
171 }
172 
test_connect_range_ec()173 void test_connect_range_ec()
174 {
175   connection_sink sink;
176   boost::asio::io_context io_context;
177   boost::asio::ip::tcp::socket socket(io_context);
178   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
179   boost::asio::ip::tcp::endpoint result;
180   boost::system::error_code ec;
181 
182   result = boost::asio::connect(socket, endpoints, ec);
183   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
184   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
185 
186   endpoints.push_back(sink.target_endpoint());
187 
188   result = boost::asio::connect(socket, endpoints, ec);
189   BOOST_ASIO_CHECK(result == endpoints[0]);
190   BOOST_ASIO_CHECK(!ec);
191 
192   endpoints.push_back(sink.target_endpoint());
193 
194   result = boost::asio::connect(socket, endpoints, ec);
195   BOOST_ASIO_CHECK(result == endpoints[0]);
196   BOOST_ASIO_CHECK(!ec);
197 
198   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
199 
200   result = boost::asio::connect(socket, endpoints, ec);
201   BOOST_ASIO_CHECK(result == endpoints[1]);
202   BOOST_ASIO_CHECK(!ec);
203 }
204 
test_connect_range_cond()205 void test_connect_range_cond()
206 {
207   connection_sink sink;
208   boost::asio::io_context io_context;
209   boost::asio::ip::tcp::socket socket(io_context);
210   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
211   boost::asio::ip::tcp::endpoint result;
212 
213   try
214   {
215     result = boost::asio::connect(socket, endpoints, true_cond_1);
216     BOOST_ASIO_CHECK(false);
217   }
218   catch (boost::system::system_error& e)
219   {
220     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
221   }
222 
223   try
224   {
225     result = boost::asio::connect(socket, endpoints, true_cond_2());
226     BOOST_ASIO_CHECK(false);
227   }
228   catch (boost::system::system_error& e)
229   {
230     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
231   }
232 
233   try
234   {
235     result = boost::asio::connect(socket, endpoints, legacy_true_cond_1);
236     BOOST_ASIO_CHECK(false);
237   }
238   catch (boost::system::system_error& e)
239   {
240     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
241   }
242 
243   try
244   {
245     result = boost::asio::connect(socket, endpoints, legacy_true_cond_2());
246     BOOST_ASIO_CHECK(false);
247   }
248   catch (boost::system::system_error& e)
249   {
250     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
251   }
252 
253   try
254   {
255     result = boost::asio::connect(socket, endpoints, false_cond);
256     BOOST_ASIO_CHECK(false);
257   }
258   catch (boost::system::system_error& e)
259   {
260     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
261   }
262 
263   endpoints.push_back(sink.target_endpoint());
264 
265   result = boost::asio::connect(socket, endpoints, true_cond_1);
266   BOOST_ASIO_CHECK(result == endpoints[0]);
267 
268   result = boost::asio::connect(socket, endpoints, true_cond_2());
269   BOOST_ASIO_CHECK(result == endpoints[0]);
270 
271   result = boost::asio::connect(socket, endpoints, legacy_true_cond_1);
272   BOOST_ASIO_CHECK(result == endpoints[0]);
273 
274   result = boost::asio::connect(socket, endpoints, legacy_true_cond_2());
275   BOOST_ASIO_CHECK(result == endpoints[0]);
276 
277   try
278   {
279     result = boost::asio::connect(socket, endpoints, false_cond);
280     BOOST_ASIO_CHECK(false);
281   }
282   catch (boost::system::system_error& e)
283   {
284     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
285   }
286 
287   endpoints.push_back(sink.target_endpoint());
288 
289   result = boost::asio::connect(socket, endpoints, true_cond_1);
290   BOOST_ASIO_CHECK(result == endpoints[0]);
291 
292   result = boost::asio::connect(socket, endpoints, true_cond_2());
293   BOOST_ASIO_CHECK(result == endpoints[0]);
294 
295   result = boost::asio::connect(socket, endpoints, legacy_true_cond_1);
296   BOOST_ASIO_CHECK(result == endpoints[0]);
297 
298   result = boost::asio::connect(socket, endpoints, legacy_true_cond_2());
299   BOOST_ASIO_CHECK(result == endpoints[0]);
300 
301   try
302   {
303     result = boost::asio::connect(socket, endpoints, false_cond);
304     BOOST_ASIO_CHECK(false);
305   }
306   catch (boost::system::system_error& e)
307   {
308     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
309   }
310 
311   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
312 
313   result = boost::asio::connect(socket, endpoints, true_cond_1);
314   BOOST_ASIO_CHECK(result == endpoints[1]);
315 
316   result = boost::asio::connect(socket, endpoints, true_cond_2());
317   BOOST_ASIO_CHECK(result == endpoints[1]);
318 
319   result = boost::asio::connect(socket, endpoints, legacy_true_cond_1);
320   BOOST_ASIO_CHECK(result == endpoints[1]);
321 
322   result = boost::asio::connect(socket, endpoints, legacy_true_cond_2());
323   BOOST_ASIO_CHECK(result == endpoints[1]);
324 
325   try
326   {
327     result = boost::asio::connect(socket, endpoints, false_cond);
328     BOOST_ASIO_CHECK(false);
329   }
330   catch (boost::system::system_error& e)
331   {
332     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
333   }
334 }
335 
test_connect_range_cond_ec()336 void test_connect_range_cond_ec()
337 {
338   connection_sink sink;
339   boost::asio::io_context io_context;
340   boost::asio::ip::tcp::socket socket(io_context);
341   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
342   boost::asio::ip::tcp::endpoint result;
343   boost::system::error_code ec;
344 
345   result = boost::asio::connect(socket, endpoints, true_cond_1, ec);
346   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
347   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
348 
349   result = boost::asio::connect(socket, endpoints, true_cond_2(), ec);
350   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
351   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
352 
353   result = boost::asio::connect(socket, endpoints, legacy_true_cond_1, ec);
354   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
355   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
356 
357   result = boost::asio::connect(socket, endpoints, legacy_true_cond_2(), ec);
358   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
359   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
360 
361   result = boost::asio::connect(socket, endpoints, false_cond, ec);
362   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
363   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
364 
365   endpoints.push_back(sink.target_endpoint());
366 
367   result = boost::asio::connect(socket, endpoints, true_cond_1, ec);
368   BOOST_ASIO_CHECK(result == endpoints[0]);
369   BOOST_ASIO_CHECK(!ec);
370 
371   result = boost::asio::connect(socket, endpoints, true_cond_2(), ec);
372   BOOST_ASIO_CHECK(result == endpoints[0]);
373   BOOST_ASIO_CHECK(!ec);
374 
375   result = boost::asio::connect(socket, endpoints, legacy_true_cond_1, ec);
376   BOOST_ASIO_CHECK(result == endpoints[0]);
377   BOOST_ASIO_CHECK(!ec);
378 
379   result = boost::asio::connect(socket, endpoints, legacy_true_cond_2(), ec);
380   BOOST_ASIO_CHECK(result == endpoints[0]);
381   BOOST_ASIO_CHECK(!ec);
382 
383   result = boost::asio::connect(socket, endpoints, false_cond, ec);
384   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
385   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
386 
387   endpoints.push_back(sink.target_endpoint());
388 
389   result = boost::asio::connect(socket, endpoints, true_cond_1, ec);
390   BOOST_ASIO_CHECK(result == endpoints[0]);
391   BOOST_ASIO_CHECK(!ec);
392 
393   result = boost::asio::connect(socket, endpoints, true_cond_2(), ec);
394   BOOST_ASIO_CHECK(result == endpoints[0]);
395   BOOST_ASIO_CHECK(!ec);
396 
397   result = boost::asio::connect(socket, endpoints, legacy_true_cond_1, ec);
398   BOOST_ASIO_CHECK(result == endpoints[0]);
399   BOOST_ASIO_CHECK(!ec);
400 
401   result = boost::asio::connect(socket, endpoints, legacy_true_cond_2(), ec);
402   BOOST_ASIO_CHECK(result == endpoints[0]);
403   BOOST_ASIO_CHECK(!ec);
404 
405   result = boost::asio::connect(socket, endpoints, false_cond, ec);
406   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
407   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
408 
409   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
410 
411   result = boost::asio::connect(socket, endpoints, true_cond_1, ec);
412   BOOST_ASIO_CHECK(result == endpoints[1]);
413   BOOST_ASIO_CHECK(!ec);
414 
415   result = boost::asio::connect(socket, endpoints, true_cond_2(), ec);
416   BOOST_ASIO_CHECK(result == endpoints[1]);
417   BOOST_ASIO_CHECK(!ec);
418 
419   result = boost::asio::connect(socket, endpoints, legacy_true_cond_1, ec);
420   BOOST_ASIO_CHECK(result == endpoints[1]);
421   BOOST_ASIO_CHECK(!ec);
422 
423   result = boost::asio::connect(socket, endpoints, legacy_true_cond_2(), ec);
424   BOOST_ASIO_CHECK(result == endpoints[1]);
425   BOOST_ASIO_CHECK(!ec);
426 
427   result = boost::asio::connect(socket, endpoints, false_cond, ec);
428   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
429   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
430 }
431 
test_connect_iter()432 void test_connect_iter()
433 {
434   connection_sink sink;
435   boost::asio::io_context io_context;
436   boost::asio::ip::tcp::socket socket(io_context);
437   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
438   const std::vector<boost::asio::ip::tcp::endpoint>& cendpoints = endpoints;
439   std::vector<boost::asio::ip::tcp::endpoint>::const_iterator result;
440 
441   try
442   {
443     result = boost::asio::connect(socket, cendpoints.begin(), cendpoints.end());
444     BOOST_ASIO_CHECK(false);
445   }
446   catch (boost::system::system_error& e)
447   {
448     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
449   }
450 
451   endpoints.push_back(sink.target_endpoint());
452 
453   result = boost::asio::connect(socket, cendpoints.begin(), cendpoints.end());
454   BOOST_ASIO_CHECK(result == cendpoints.begin());
455 
456   endpoints.push_back(sink.target_endpoint());
457 
458   result = boost::asio::connect(socket, cendpoints.begin(), cendpoints.end());
459   BOOST_ASIO_CHECK(result == cendpoints.begin());
460 
461   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
462 
463   result = boost::asio::connect(socket, cendpoints.begin(), cendpoints.end());
464   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
465 }
466 
test_connect_iter_ec()467 void test_connect_iter_ec()
468 {
469   connection_sink sink;
470   boost::asio::io_context io_context;
471   boost::asio::ip::tcp::socket socket(io_context);
472   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
473   const std::vector<boost::asio::ip::tcp::endpoint>& cendpoints = endpoints;
474   std::vector<boost::asio::ip::tcp::endpoint>::const_iterator result;
475   boost::system::error_code ec;
476 
477   result = boost::asio::connect(socket,
478       cendpoints.begin(), cendpoints.end(), ec);
479   BOOST_ASIO_CHECK(result == cendpoints.end());
480   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
481 
482   endpoints.push_back(sink.target_endpoint());
483 
484   result = boost::asio::connect(socket,
485       cendpoints.begin(), cendpoints.end(), ec);
486   BOOST_ASIO_CHECK(result == cendpoints.begin());
487   BOOST_ASIO_CHECK(!ec);
488 
489   endpoints.push_back(sink.target_endpoint());
490 
491   result = boost::asio::connect(socket,
492       cendpoints.begin(), cendpoints.end(), ec);
493   BOOST_ASIO_CHECK(result == cendpoints.begin());
494   BOOST_ASIO_CHECK(!ec);
495 
496   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
497 
498   result = boost::asio::connect(socket,
499       cendpoints.begin(), cendpoints.end(), ec);
500   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
501   BOOST_ASIO_CHECK(!ec);
502 }
503 
test_connect_iter_cond()504 void test_connect_iter_cond()
505 {
506   connection_sink sink;
507   boost::asio::io_context io_context;
508   boost::asio::ip::tcp::socket socket(io_context);
509   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
510   const std::vector<boost::asio::ip::tcp::endpoint>& cendpoints = endpoints;
511   std::vector<boost::asio::ip::tcp::endpoint>::const_iterator result;
512 
513   try
514   {
515     result = boost::asio::connect(socket, cendpoints.begin(),
516         cendpoints.end(), true_cond_1);
517     BOOST_ASIO_CHECK(false);
518   }
519   catch (boost::system::system_error& e)
520   {
521     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
522   }
523 
524   try
525   {
526     result = boost::asio::connect(socket, cendpoints.begin(),
527         cendpoints.end(), true_cond_2());
528     BOOST_ASIO_CHECK(false);
529   }
530   catch (boost::system::system_error& e)
531   {
532     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
533   }
534 
535   try
536   {
537     result = boost::asio::connect(socket, cendpoints.begin(),
538         cendpoints.end(), legacy_true_cond_1);
539     BOOST_ASIO_CHECK(false);
540   }
541   catch (boost::system::system_error& e)
542   {
543     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
544   }
545 
546   try
547   {
548     result = boost::asio::connect(socket, cendpoints.begin(),
549         cendpoints.end(), legacy_true_cond_2());
550     BOOST_ASIO_CHECK(false);
551   }
552   catch (boost::system::system_error& e)
553   {
554     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
555   }
556 
557   try
558   {
559     result = boost::asio::connect(socket, cendpoints.begin(),
560         cendpoints.end(), false_cond);
561     BOOST_ASIO_CHECK(false);
562   }
563   catch (boost::system::system_error& e)
564   {
565     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
566   }
567 
568   endpoints.push_back(sink.target_endpoint());
569 
570   result = boost::asio::connect(socket, cendpoints.begin(),
571       cendpoints.end(), true_cond_1);
572   BOOST_ASIO_CHECK(result == cendpoints.begin());
573 
574   result = boost::asio::connect(socket, cendpoints.begin(),
575       cendpoints.end(), true_cond_2());
576   BOOST_ASIO_CHECK(result == cendpoints.begin());
577 
578   result = boost::asio::connect(socket, cendpoints.begin(),
579       cendpoints.end(), legacy_true_cond_1);
580   BOOST_ASIO_CHECK(result == cendpoints.begin());
581 
582   result = boost::asio::connect(socket, cendpoints.begin(),
583       cendpoints.end(), legacy_true_cond_2());
584   BOOST_ASIO_CHECK(result == cendpoints.begin());
585 
586   try
587   {
588     result = boost::asio::connect(socket, cendpoints.begin(),
589         cendpoints.end(), false_cond);
590     BOOST_ASIO_CHECK(false);
591   }
592   catch (boost::system::system_error& e)
593   {
594     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
595   }
596 
597   endpoints.push_back(sink.target_endpoint());
598 
599   result = boost::asio::connect(socket, cendpoints.begin(),
600       cendpoints.end(), true_cond_1);
601   BOOST_ASIO_CHECK(result == cendpoints.begin());
602 
603   result = boost::asio::connect(socket, cendpoints.begin(),
604       cendpoints.end(), true_cond_2());
605   BOOST_ASIO_CHECK(result == cendpoints.begin());
606 
607   result = boost::asio::connect(socket, cendpoints.begin(),
608       cendpoints.end(), legacy_true_cond_1);
609   BOOST_ASIO_CHECK(result == cendpoints.begin());
610 
611   result = boost::asio::connect(socket, cendpoints.begin(),
612       cendpoints.end(), legacy_true_cond_2());
613   BOOST_ASIO_CHECK(result == cendpoints.begin());
614 
615   try
616   {
617     result = boost::asio::connect(socket, cendpoints.begin(),
618         cendpoints.end(), false_cond);
619     BOOST_ASIO_CHECK(false);
620   }
621   catch (boost::system::system_error& e)
622   {
623     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
624   }
625 
626   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
627 
628   result = boost::asio::connect(socket, cendpoints.begin(),
629       cendpoints.end(), true_cond_1);
630   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
631 
632   result = boost::asio::connect(socket, cendpoints.begin(),
633       cendpoints.end(), true_cond_2());
634   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
635 
636   result = boost::asio::connect(socket, cendpoints.begin(),
637       cendpoints.end(), legacy_true_cond_1);
638   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
639 
640   result = boost::asio::connect(socket, cendpoints.begin(),
641       cendpoints.end(), legacy_true_cond_2());
642   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
643 
644   try
645   {
646     result = boost::asio::connect(socket, cendpoints.begin(),
647         cendpoints.end(), false_cond);
648     BOOST_ASIO_CHECK(false);
649   }
650   catch (boost::system::system_error& e)
651   {
652     BOOST_ASIO_CHECK(e.code() == boost::asio::error::not_found);
653   }
654 }
655 
test_connect_iter_cond_ec()656 void test_connect_iter_cond_ec()
657 {
658   connection_sink sink;
659   boost::asio::io_context io_context;
660   boost::asio::ip::tcp::socket socket(io_context);
661   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
662   const std::vector<boost::asio::ip::tcp::endpoint>& cendpoints = endpoints;
663   std::vector<boost::asio::ip::tcp::endpoint>::const_iterator result;
664   boost::system::error_code ec;
665 
666   result = boost::asio::connect(socket, cendpoints.begin(),
667       cendpoints.end(), true_cond_1, ec);
668   BOOST_ASIO_CHECK(result == cendpoints.end());
669   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
670 
671   result = boost::asio::connect(socket, cendpoints.begin(),
672       cendpoints.end(), true_cond_2(), ec);
673   BOOST_ASIO_CHECK(result == cendpoints.end());
674   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
675 
676   result = boost::asio::connect(socket, cendpoints.begin(),
677       cendpoints.end(), legacy_true_cond_1, ec);
678   BOOST_ASIO_CHECK(result == cendpoints.end());
679   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
680 
681   result = boost::asio::connect(socket, cendpoints.begin(),
682       cendpoints.end(), legacy_true_cond_2(), ec);
683   BOOST_ASIO_CHECK(result == cendpoints.end());
684   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
685 
686   result = boost::asio::connect(socket, cendpoints.begin(),
687       cendpoints.end(), false_cond, ec);
688   BOOST_ASIO_CHECK(result == cendpoints.end());
689   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
690 
691   endpoints.push_back(sink.target_endpoint());
692 
693   result = boost::asio::connect(socket, cendpoints.begin(),
694       cendpoints.end(), true_cond_1, ec);
695   BOOST_ASIO_CHECK(result == cendpoints.begin());
696   BOOST_ASIO_CHECK(!ec);
697 
698   result = boost::asio::connect(socket, cendpoints.begin(),
699       cendpoints.end(), true_cond_2(), ec);
700   BOOST_ASIO_CHECK(result == cendpoints.begin());
701   BOOST_ASIO_CHECK(!ec);
702 
703   result = boost::asio::connect(socket, cendpoints.begin(),
704       cendpoints.end(), legacy_true_cond_1, ec);
705   BOOST_ASIO_CHECK(result == cendpoints.begin());
706   BOOST_ASIO_CHECK(!ec);
707 
708   result = boost::asio::connect(socket, cendpoints.begin(),
709       cendpoints.end(), legacy_true_cond_2(), ec);
710   BOOST_ASIO_CHECK(result == cendpoints.begin());
711   BOOST_ASIO_CHECK(!ec);
712 
713   result = boost::asio::connect(socket, cendpoints.begin(),
714       cendpoints.end(), false_cond, ec);
715   BOOST_ASIO_CHECK(result == cendpoints.end());
716   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
717 
718   endpoints.push_back(sink.target_endpoint());
719 
720   result = boost::asio::connect(socket, cendpoints.begin(),
721       cendpoints.end(), true_cond_1, ec);
722   BOOST_ASIO_CHECK(result == cendpoints.begin());
723   BOOST_ASIO_CHECK(!ec);
724 
725   result = boost::asio::connect(socket, cendpoints.begin(),
726       cendpoints.end(), true_cond_2(), ec);
727   BOOST_ASIO_CHECK(result == cendpoints.begin());
728   BOOST_ASIO_CHECK(!ec);
729 
730   result = boost::asio::connect(socket, cendpoints.begin(),
731       cendpoints.end(), legacy_true_cond_1, ec);
732   BOOST_ASIO_CHECK(result == cendpoints.begin());
733   BOOST_ASIO_CHECK(!ec);
734 
735   result = boost::asio::connect(socket, cendpoints.begin(),
736       cendpoints.end(), legacy_true_cond_2(), ec);
737   BOOST_ASIO_CHECK(result == cendpoints.begin());
738   BOOST_ASIO_CHECK(!ec);
739 
740   result = boost::asio::connect(socket, cendpoints.begin(),
741       cendpoints.end(), false_cond, ec);
742   BOOST_ASIO_CHECK(result == cendpoints.end());
743   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
744 
745   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
746 
747   result = boost::asio::connect(socket, cendpoints.begin(),
748       cendpoints.end(), true_cond_1, ec);
749   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
750   BOOST_ASIO_CHECK(!ec);
751 
752   result = boost::asio::connect(socket, cendpoints.begin(),
753       cendpoints.end(), true_cond_2(), ec);
754   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
755   BOOST_ASIO_CHECK(!ec);
756 
757   result = boost::asio::connect(socket, cendpoints.begin(),
758       cendpoints.end(), legacy_true_cond_1, ec);
759   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
760   BOOST_ASIO_CHECK(!ec);
761 
762   result = boost::asio::connect(socket, cendpoints.begin(),
763       cendpoints.end(), legacy_true_cond_2(), ec);
764   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
765   BOOST_ASIO_CHECK(!ec);
766 
767   result = boost::asio::connect(socket, cendpoints.begin(),
768       cendpoints.end(), false_cond, ec);
769   BOOST_ASIO_CHECK(result == cendpoints.end());
770   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
771 }
772 
test_async_connect_range()773 void test_async_connect_range()
774 {
775   connection_sink sink;
776   boost::asio::io_context io_context;
777   boost::asio::ip::tcp::socket socket(io_context);
778   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
779   boost::asio::ip::tcp::endpoint result;
780   boost::system::error_code ec;
781 
782   boost::asio::async_connect(socket, endpoints,
783       bindns::bind(range_handler, _1, _2, &ec, &result));
784   io_context.restart();
785   io_context.run();
786   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
787   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
788 
789   endpoints.push_back(sink.target_endpoint());
790 
791   boost::asio::async_connect(socket, endpoints,
792       bindns::bind(range_handler, _1, _2, &ec, &result));
793   io_context.restart();
794   io_context.run();
795   BOOST_ASIO_CHECK(result == endpoints[0]);
796   BOOST_ASIO_CHECK(!ec);
797 
798   endpoints.push_back(sink.target_endpoint());
799 
800   boost::asio::async_connect(socket, endpoints,
801       bindns::bind(range_handler, _1, _2, &ec, &result));
802   io_context.restart();
803   io_context.run();
804   BOOST_ASIO_CHECK(result == endpoints[0]);
805   BOOST_ASIO_CHECK(!ec);
806 
807   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
808 
809   boost::asio::async_connect(socket, endpoints,
810       bindns::bind(range_handler, _1, _2, &ec, &result));
811   io_context.restart();
812   io_context.run();
813   BOOST_ASIO_CHECK(result == endpoints[1]);
814   BOOST_ASIO_CHECK(!ec);
815 }
816 
test_async_connect_range_cond()817 void test_async_connect_range_cond()
818 {
819   connection_sink sink;
820   boost::asio::io_context io_context;
821   boost::asio::ip::tcp::socket socket(io_context);
822   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
823   boost::asio::ip::tcp::endpoint result;
824   boost::system::error_code ec;
825 
826   boost::asio::async_connect(socket, endpoints, true_cond_1,
827       bindns::bind(range_handler, _1, _2, &ec, &result));
828   io_context.restart();
829   io_context.run();
830   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
831   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
832 
833   boost::asio::async_connect(socket, endpoints, true_cond_2(),
834       bindns::bind(range_handler, _1, _2, &ec, &result));
835   io_context.restart();
836   io_context.run();
837   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
838   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
839 
840   boost::asio::async_connect(socket, endpoints, legacy_true_cond_1,
841       bindns::bind(range_handler, _1, _2, &ec, &result));
842   io_context.restart();
843   io_context.run();
844   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
845   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
846 
847   boost::asio::async_connect(socket, endpoints, legacy_true_cond_2(),
848       bindns::bind(range_handler, _1, _2, &ec, &result));
849   io_context.restart();
850   io_context.run();
851   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
852   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
853 
854   boost::asio::async_connect(socket, endpoints, false_cond,
855       bindns::bind(range_handler, _1, _2, &ec, &result));
856   io_context.restart();
857   io_context.run();
858   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
859   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
860 
861   endpoints.push_back(sink.target_endpoint());
862 
863   boost::asio::async_connect(socket, endpoints, true_cond_1,
864       bindns::bind(range_handler, _1, _2, &ec, &result));
865   io_context.restart();
866   io_context.run();
867   BOOST_ASIO_CHECK(result == endpoints[0]);
868   BOOST_ASIO_CHECK(!ec);
869 
870   boost::asio::async_connect(socket, endpoints, true_cond_2(),
871       bindns::bind(range_handler, _1, _2, &ec, &result));
872   io_context.restart();
873   io_context.run();
874   BOOST_ASIO_CHECK(result == endpoints[0]);
875   BOOST_ASIO_CHECK(!ec);
876 
877   boost::asio::async_connect(socket, endpoints, legacy_true_cond_1,
878       bindns::bind(range_handler, _1, _2, &ec, &result));
879   io_context.restart();
880   io_context.run();
881   BOOST_ASIO_CHECK(result == endpoints[0]);
882   BOOST_ASIO_CHECK(!ec);
883 
884   boost::asio::async_connect(socket, endpoints, legacy_true_cond_2(),
885       bindns::bind(range_handler, _1, _2, &ec, &result));
886   io_context.restart();
887   io_context.run();
888   BOOST_ASIO_CHECK(result == endpoints[0]);
889   BOOST_ASIO_CHECK(!ec);
890 
891   boost::asio::async_connect(socket, endpoints, false_cond,
892       bindns::bind(range_handler, _1, _2, &ec, &result));
893   io_context.restart();
894   io_context.run();
895   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
896   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
897 
898   endpoints.push_back(sink.target_endpoint());
899 
900   boost::asio::async_connect(socket, endpoints, true_cond_1,
901       bindns::bind(range_handler, _1, _2, &ec, &result));
902   io_context.restart();
903   io_context.run();
904   BOOST_ASIO_CHECK(result == endpoints[0]);
905   BOOST_ASIO_CHECK(!ec);
906 
907   boost::asio::async_connect(socket, endpoints, true_cond_2(),
908       bindns::bind(range_handler, _1, _2, &ec, &result));
909   io_context.restart();
910   io_context.run();
911   BOOST_ASIO_CHECK(result == endpoints[0]);
912   BOOST_ASIO_CHECK(!ec);
913 
914   boost::asio::async_connect(socket, endpoints, legacy_true_cond_1,
915       bindns::bind(range_handler, _1, _2, &ec, &result));
916   io_context.restart();
917   io_context.run();
918   BOOST_ASIO_CHECK(result == endpoints[0]);
919   BOOST_ASIO_CHECK(!ec);
920 
921   boost::asio::async_connect(socket, endpoints, legacy_true_cond_2(),
922       bindns::bind(range_handler, _1, _2, &ec, &result));
923   io_context.restart();
924   io_context.run();
925   BOOST_ASIO_CHECK(result == endpoints[0]);
926   BOOST_ASIO_CHECK(!ec);
927 
928   boost::asio::async_connect(socket, endpoints, false_cond,
929       bindns::bind(range_handler, _1, _2, &ec, &result));
930   io_context.restart();
931   io_context.run();
932   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
933   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
934 
935   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
936 
937   boost::asio::async_connect(socket, endpoints, true_cond_1,
938       bindns::bind(range_handler, _1, _2, &ec, &result));
939   io_context.restart();
940   io_context.run();
941   BOOST_ASIO_CHECK(result == endpoints[1]);
942   BOOST_ASIO_CHECK(!ec);
943 
944   boost::asio::async_connect(socket, endpoints, true_cond_2(),
945       bindns::bind(range_handler, _1, _2, &ec, &result));
946   io_context.restart();
947   io_context.run();
948   BOOST_ASIO_CHECK(result == endpoints[1]);
949   BOOST_ASIO_CHECK(!ec);
950 
951   boost::asio::async_connect(socket, endpoints, legacy_true_cond_1,
952       bindns::bind(range_handler, _1, _2, &ec, &result));
953   io_context.restart();
954   io_context.run();
955   BOOST_ASIO_CHECK(result == endpoints[1]);
956   BOOST_ASIO_CHECK(!ec);
957 
958   boost::asio::async_connect(socket, endpoints, legacy_true_cond_2(),
959       bindns::bind(range_handler, _1, _2, &ec, &result));
960   io_context.restart();
961   io_context.run();
962   BOOST_ASIO_CHECK(result == endpoints[1]);
963   BOOST_ASIO_CHECK(!ec);
964 
965   boost::asio::async_connect(socket, endpoints, false_cond,
966       bindns::bind(range_handler, _1, _2, &ec, &result));
967   io_context.restart();
968   io_context.run();
969   BOOST_ASIO_CHECK(result == boost::asio::ip::tcp::endpoint());
970   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
971 }
972 
test_async_connect_iter()973 void test_async_connect_iter()
974 {
975   connection_sink sink;
976   boost::asio::io_context io_context;
977   boost::asio::ip::tcp::socket socket(io_context);
978   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
979   const std::vector<boost::asio::ip::tcp::endpoint>& cendpoints = endpoints;
980   std::vector<boost::asio::ip::tcp::endpoint>::const_iterator result;
981   boost::system::error_code ec;
982 
983   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
984       bindns::bind(iter_handler, _1, _2, &ec, &result));
985   io_context.restart();
986   io_context.run();
987   BOOST_ASIO_CHECK(result == cendpoints.end());
988   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
989 
990   endpoints.push_back(sink.target_endpoint());
991 
992   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
993       bindns::bind(iter_handler, _1, _2, &ec, &result));
994   io_context.restart();
995   io_context.run();
996   BOOST_ASIO_CHECK(result == cendpoints.begin());
997   BOOST_ASIO_CHECK(!ec);
998 
999   endpoints.push_back(sink.target_endpoint());
1000 
1001   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1002       bindns::bind(iter_handler, _1, _2, &ec, &result));
1003   io_context.restart();
1004   io_context.run();
1005   BOOST_ASIO_CHECK(result == cendpoints.begin());
1006   BOOST_ASIO_CHECK(!ec);
1007 
1008   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
1009 
1010   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1011       bindns::bind(iter_handler, _1, _2, &ec, &result));
1012   io_context.restart();
1013   io_context.run();
1014   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
1015   BOOST_ASIO_CHECK(!ec);
1016 }
1017 
test_async_connect_iter_cond()1018 void test_async_connect_iter_cond()
1019 {
1020   connection_sink sink;
1021   boost::asio::io_context io_context;
1022   boost::asio::ip::tcp::socket socket(io_context);
1023   std::vector<boost::asio::ip::tcp::endpoint> endpoints;
1024   const std::vector<boost::asio::ip::tcp::endpoint>& cendpoints = endpoints;
1025   std::vector<boost::asio::ip::tcp::endpoint>::const_iterator result;
1026   boost::system::error_code ec;
1027 
1028   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1029       true_cond_1, bindns::bind(iter_handler, _1, _2, &ec, &result));
1030   io_context.restart();
1031   io_context.run();
1032   BOOST_ASIO_CHECK(result == cendpoints.end());
1033   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1034 
1035   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1036       true_cond_2(), bindns::bind(iter_handler, _1, _2, &ec, &result));
1037   io_context.restart();
1038   io_context.run();
1039   BOOST_ASIO_CHECK(result == cendpoints.end());
1040   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1041 
1042   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1043       legacy_true_cond_1, bindns::bind(iter_handler, _1, _2, &ec, &result));
1044   io_context.restart();
1045   io_context.run();
1046   BOOST_ASIO_CHECK(result == cendpoints.end());
1047   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1048 
1049   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1050       legacy_true_cond_2(), bindns::bind(iter_handler, _1, _2, &ec, &result));
1051   io_context.restart();
1052   io_context.run();
1053   BOOST_ASIO_CHECK(result == cendpoints.end());
1054   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1055 
1056   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1057       false_cond, bindns::bind(iter_handler, _1, _2, &ec, &result));
1058   io_context.restart();
1059   io_context.run();
1060   BOOST_ASIO_CHECK(result == cendpoints.end());
1061   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1062 
1063   endpoints.push_back(sink.target_endpoint());
1064 
1065   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1066       true_cond_1, bindns::bind(iter_handler, _1, _2, &ec, &result));
1067   io_context.restart();
1068   io_context.run();
1069   BOOST_ASIO_CHECK(result == cendpoints.begin());
1070   BOOST_ASIO_CHECK(!ec);
1071 
1072   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1073       true_cond_2(), bindns::bind(iter_handler, _1, _2, &ec, &result));
1074   io_context.restart();
1075   io_context.run();
1076   BOOST_ASIO_CHECK(result == cendpoints.begin());
1077   BOOST_ASIO_CHECK(!ec);
1078 
1079   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1080       legacy_true_cond_1, bindns::bind(iter_handler, _1, _2, &ec, &result));
1081   io_context.restart();
1082   io_context.run();
1083   BOOST_ASIO_CHECK(result == cendpoints.begin());
1084   BOOST_ASIO_CHECK(!ec);
1085 
1086   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1087       legacy_true_cond_2(), bindns::bind(iter_handler, _1, _2, &ec, &result));
1088   io_context.restart();
1089   io_context.run();
1090   BOOST_ASIO_CHECK(result == cendpoints.begin());
1091   BOOST_ASIO_CHECK(!ec);
1092 
1093   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1094       false_cond, bindns::bind(iter_handler, _1, _2, &ec, &result));
1095   io_context.restart();
1096   io_context.run();
1097   BOOST_ASIO_CHECK(result == cendpoints.end());
1098   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1099 
1100   endpoints.push_back(sink.target_endpoint());
1101 
1102   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1103       true_cond_1, bindns::bind(iter_handler, _1, _2, &ec, &result));
1104   io_context.restart();
1105   io_context.run();
1106   BOOST_ASIO_CHECK(result == cendpoints.begin());
1107   BOOST_ASIO_CHECK(!ec);
1108 
1109   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1110       true_cond_2(), bindns::bind(iter_handler, _1, _2, &ec, &result));
1111   io_context.restart();
1112   io_context.run();
1113   BOOST_ASIO_CHECK(result == cendpoints.begin());
1114   BOOST_ASIO_CHECK(!ec);
1115 
1116   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1117       legacy_true_cond_1, bindns::bind(iter_handler, _1, _2, &ec, &result));
1118   io_context.restart();
1119   io_context.run();
1120   BOOST_ASIO_CHECK(result == cendpoints.begin());
1121   BOOST_ASIO_CHECK(!ec);
1122 
1123   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1124       legacy_true_cond_2(), bindns::bind(iter_handler, _1, _2, &ec, &result));
1125   io_context.restart();
1126   io_context.run();
1127   BOOST_ASIO_CHECK(result == cendpoints.begin());
1128   BOOST_ASIO_CHECK(!ec);
1129 
1130   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1131       false_cond, bindns::bind(iter_handler, _1, _2, &ec, &result));
1132   io_context.restart();
1133   io_context.run();
1134   BOOST_ASIO_CHECK(result == cendpoints.end());
1135   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1136 
1137   endpoints.insert(endpoints.begin(), boost::asio::ip::tcp::endpoint());
1138 
1139   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1140       true_cond_1, bindns::bind(iter_handler, _1, _2, &ec, &result));
1141   io_context.restart();
1142   io_context.run();
1143   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
1144   BOOST_ASIO_CHECK(!ec);
1145 
1146   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1147       true_cond_2(), bindns::bind(iter_handler, _1, _2, &ec, &result));
1148   io_context.restart();
1149   io_context.run();
1150   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
1151   BOOST_ASIO_CHECK(!ec);
1152 
1153   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1154       legacy_true_cond_1, bindns::bind(iter_handler, _1, _2, &ec, &result));
1155   io_context.restart();
1156   io_context.run();
1157   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
1158   BOOST_ASIO_CHECK(!ec);
1159 
1160   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1161       legacy_true_cond_2(), bindns::bind(iter_handler, _1, _2, &ec, &result));
1162   io_context.restart();
1163   io_context.run();
1164   BOOST_ASIO_CHECK(result == cendpoints.begin() + 1);
1165   BOOST_ASIO_CHECK(!ec);
1166 
1167   boost::asio::async_connect(socket, cendpoints.begin(), cendpoints.end(),
1168       false_cond, bindns::bind(iter_handler, _1, _2, &ec, &result));
1169   io_context.restart();
1170   io_context.run();
1171   BOOST_ASIO_CHECK(result == cendpoints.end());
1172   BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1173 }
1174 
1175 BOOST_ASIO_TEST_SUITE
1176 (
1177   "connect",
1178   BOOST_ASIO_TEST_CASE(test_connect_range)
1179   BOOST_ASIO_TEST_CASE(test_connect_range_ec)
1180   BOOST_ASIO_TEST_CASE(test_connect_range_cond)
1181   BOOST_ASIO_TEST_CASE(test_connect_range_cond_ec)
1182   BOOST_ASIO_TEST_CASE(test_connect_iter)
1183   BOOST_ASIO_TEST_CASE(test_connect_iter_ec)
1184   BOOST_ASIO_TEST_CASE(test_connect_iter_cond)
1185   BOOST_ASIO_TEST_CASE(test_connect_iter_cond_ec)
1186   BOOST_ASIO_TEST_CASE(test_async_connect_range)
1187   BOOST_ASIO_TEST_CASE(test_async_connect_range_cond)
1188   BOOST_ASIO_TEST_CASE(test_async_connect_iter)
1189   BOOST_ASIO_TEST_CASE(test_async_connect_iter_cond)
1190 )
1191