1 //
2 // connect.cpp
3 // ~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2019 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 "asio/connect.hpp"
18 
19 #include <vector>
20 #include "asio/detail/thread.hpp"
21 #include "asio/ip/tcp.hpp"
22 
23 #if defined(ASIO_HAS_BOOST_BIND)
24 # include <boost/bind.hpp>
25 #else // defined(ASIO_HAS_BOOST_BIND)
26 # include <functional>
27 #endif // defined(ASIO_HAS_BOOST_BIND)
28 
29 #include "unit_test.hpp"
30 
31 #if defined(ASIO_HAS_BOOST_BIND)
32 namespace bindns = boost;
33 #else // defined(ASIO_HAS_BOOST_BIND)
34 namespace bindns = std;
35 using std::placeholders::_1;
36 using std::placeholders::_2;
37 #endif // defined(ASIO_HAS_BOOST_BIND)
38 
39 class connection_sink
40 {
41 public:
connection_sink()42   connection_sink()
43     : acceptor_(io_context_,
44         asio::ip::tcp::endpoint(
45           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   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   asio::io_context io_context_;
77   asio::ip::tcp::acceptor acceptor_;
78   asio::ip::tcp::endpoint target_endpoint_;
79   asio::ip::tcp::socket socket_;
80   asio::detail::thread thread_;
81 };
82 
true_cond_1(const asio::error_code &,const asio::ip::tcp::endpoint &)83 bool true_cond_1(const asio::error_code& /*ec*/,
84     const 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 asio::error_code& /*ec*/,
93       const Endpoint& /*endpoint*/)
94   {
95     return true;
96   }
97 };
98 
legacy_true_cond_1(const asio::error_code &,std::vector<asio::ip::tcp::endpoint>::const_iterator next)99 std::vector<asio::ip::tcp::endpoint>::const_iterator legacy_true_cond_1(
100     const asio::error_code& /*ec*/,
101     std::vector<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 asio::error_code& /*ec*/, Iterator next)
110   {
111     return next;
112   }
113 };
114 
false_cond(const asio::error_code &,const asio::ip::tcp::endpoint &)115 bool false_cond(const asio::error_code& /*ec*/,
116     const asio::ip::tcp::endpoint& /*endpoint*/)
117 {
118   return false;
119 }
120 
range_handler(const asio::error_code & ec,const asio::ip::tcp::endpoint & endpoint,asio::error_code * out_ec,asio::ip::tcp::endpoint * out_endpoint)121 void range_handler(const asio::error_code& ec,
122     const asio::ip::tcp::endpoint& endpoint,
123     asio::error_code* out_ec,
124     asio::ip::tcp::endpoint* out_endpoint)
125 {
126   *out_ec = ec;
127   *out_endpoint = endpoint;
128 }
129 
iter_handler(const asio::error_code & ec,std::vector<asio::ip::tcp::endpoint>::const_iterator iter,asio::error_code * out_ec,std::vector<asio::ip::tcp::endpoint>::const_iterator * out_iter)130 void iter_handler(const asio::error_code& ec,
131     std::vector<asio::ip::tcp::endpoint>::const_iterator iter,
132     asio::error_code* out_ec,
133     std::vector<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   asio::io_context io_context;
143   asio::ip::tcp::socket socket(io_context);
144   std::vector<asio::ip::tcp::endpoint> endpoints;
145   asio::ip::tcp::endpoint result;
146 
147   try
148   {
149     result = asio::connect(socket, endpoints);
150     ASIO_CHECK(false);
151   }
152   catch (asio::system_error& e)
153   {
154     ASIO_CHECK(e.code() == asio::error::not_found);
155   }
156 
157   endpoints.push_back(sink.target_endpoint());
158 
159   result = asio::connect(socket, endpoints);
160   ASIO_CHECK(result == endpoints[0]);
161 
162   endpoints.push_back(sink.target_endpoint());
163 
164   result = asio::connect(socket, endpoints);
165   ASIO_CHECK(result == endpoints[0]);
166 
167   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
168 
169   result = asio::connect(socket, endpoints);
170   ASIO_CHECK(result == endpoints[1]);
171 }
172 
test_connect_range_ec()173 void test_connect_range_ec()
174 {
175   connection_sink sink;
176   asio::io_context io_context;
177   asio::ip::tcp::socket socket(io_context);
178   std::vector<asio::ip::tcp::endpoint> endpoints;
179   asio::ip::tcp::endpoint result;
180   asio::error_code ec;
181 
182   result = asio::connect(socket, endpoints, ec);
183   ASIO_CHECK(result == asio::ip::tcp::endpoint());
184   ASIO_CHECK(ec == asio::error::not_found);
185 
186   endpoints.push_back(sink.target_endpoint());
187 
188   result = asio::connect(socket, endpoints, ec);
189   ASIO_CHECK(result == endpoints[0]);
190   ASIO_CHECK(!ec);
191 
192   endpoints.push_back(sink.target_endpoint());
193 
194   result = asio::connect(socket, endpoints, ec);
195   ASIO_CHECK(result == endpoints[0]);
196   ASIO_CHECK(!ec);
197 
198   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
199 
200   result = asio::connect(socket, endpoints, ec);
201   ASIO_CHECK(result == endpoints[1]);
202   ASIO_CHECK(!ec);
203 }
204 
test_connect_range_cond()205 void test_connect_range_cond()
206 {
207   connection_sink sink;
208   asio::io_context io_context;
209   asio::ip::tcp::socket socket(io_context);
210   std::vector<asio::ip::tcp::endpoint> endpoints;
211   asio::ip::tcp::endpoint result;
212 
213   try
214   {
215     result = asio::connect(socket, endpoints, true_cond_1);
216     ASIO_CHECK(false);
217   }
218   catch (asio::system_error& e)
219   {
220     ASIO_CHECK(e.code() == asio::error::not_found);
221   }
222 
223   try
224   {
225     result = asio::connect(socket, endpoints, true_cond_2());
226     ASIO_CHECK(false);
227   }
228   catch (asio::system_error& e)
229   {
230     ASIO_CHECK(e.code() == asio::error::not_found);
231   }
232 
233   try
234   {
235     result = asio::connect(socket, endpoints, legacy_true_cond_1);
236     ASIO_CHECK(false);
237   }
238   catch (asio::system_error& e)
239   {
240     ASIO_CHECK(e.code() == asio::error::not_found);
241   }
242 
243   try
244   {
245     result = asio::connect(socket, endpoints, legacy_true_cond_2());
246     ASIO_CHECK(false);
247   }
248   catch (asio::system_error& e)
249   {
250     ASIO_CHECK(e.code() == asio::error::not_found);
251   }
252 
253   try
254   {
255     result = asio::connect(socket, endpoints, false_cond);
256     ASIO_CHECK(false);
257   }
258   catch (asio::system_error& e)
259   {
260     ASIO_CHECK(e.code() == asio::error::not_found);
261   }
262 
263   endpoints.push_back(sink.target_endpoint());
264 
265   result = asio::connect(socket, endpoints, true_cond_1);
266   ASIO_CHECK(result == endpoints[0]);
267 
268   result = asio::connect(socket, endpoints, true_cond_2());
269   ASIO_CHECK(result == endpoints[0]);
270 
271   result = asio::connect(socket, endpoints, legacy_true_cond_1);
272   ASIO_CHECK(result == endpoints[0]);
273 
274   result = asio::connect(socket, endpoints, legacy_true_cond_2());
275   ASIO_CHECK(result == endpoints[0]);
276 
277   try
278   {
279     result = asio::connect(socket, endpoints, false_cond);
280     ASIO_CHECK(false);
281   }
282   catch (asio::system_error& e)
283   {
284     ASIO_CHECK(e.code() == asio::error::not_found);
285   }
286 
287   endpoints.push_back(sink.target_endpoint());
288 
289   result = asio::connect(socket, endpoints, true_cond_1);
290   ASIO_CHECK(result == endpoints[0]);
291 
292   result = asio::connect(socket, endpoints, true_cond_2());
293   ASIO_CHECK(result == endpoints[0]);
294 
295   result = asio::connect(socket, endpoints, legacy_true_cond_1);
296   ASIO_CHECK(result == endpoints[0]);
297 
298   result = asio::connect(socket, endpoints, legacy_true_cond_2());
299   ASIO_CHECK(result == endpoints[0]);
300 
301   try
302   {
303     result = asio::connect(socket, endpoints, false_cond);
304     ASIO_CHECK(false);
305   }
306   catch (asio::system_error& e)
307   {
308     ASIO_CHECK(e.code() == asio::error::not_found);
309   }
310 
311   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
312 
313   result = asio::connect(socket, endpoints, true_cond_1);
314   ASIO_CHECK(result == endpoints[1]);
315 
316   result = asio::connect(socket, endpoints, true_cond_2());
317   ASIO_CHECK(result == endpoints[1]);
318 
319   result = asio::connect(socket, endpoints, legacy_true_cond_1);
320   ASIO_CHECK(result == endpoints[1]);
321 
322   result = asio::connect(socket, endpoints, legacy_true_cond_2());
323   ASIO_CHECK(result == endpoints[1]);
324 
325   try
326   {
327     result = asio::connect(socket, endpoints, false_cond);
328     ASIO_CHECK(false);
329   }
330   catch (asio::system_error& e)
331   {
332     ASIO_CHECK(e.code() == 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   asio::io_context io_context;
340   asio::ip::tcp::socket socket(io_context);
341   std::vector<asio::ip::tcp::endpoint> endpoints;
342   asio::ip::tcp::endpoint result;
343   asio::error_code ec;
344 
345   result = asio::connect(socket, endpoints, true_cond_1, ec);
346   ASIO_CHECK(result == asio::ip::tcp::endpoint());
347   ASIO_CHECK(ec == asio::error::not_found);
348 
349   result = asio::connect(socket, endpoints, true_cond_2(), ec);
350   ASIO_CHECK(result == asio::ip::tcp::endpoint());
351   ASIO_CHECK(ec == asio::error::not_found);
352 
353   result = asio::connect(socket, endpoints, legacy_true_cond_1, ec);
354   ASIO_CHECK(result == asio::ip::tcp::endpoint());
355   ASIO_CHECK(ec == asio::error::not_found);
356 
357   result = asio::connect(socket, endpoints, legacy_true_cond_2(), ec);
358   ASIO_CHECK(result == asio::ip::tcp::endpoint());
359   ASIO_CHECK(ec == asio::error::not_found);
360 
361   result = asio::connect(socket, endpoints, false_cond, ec);
362   ASIO_CHECK(result == asio::ip::tcp::endpoint());
363   ASIO_CHECK(ec == asio::error::not_found);
364 
365   endpoints.push_back(sink.target_endpoint());
366 
367   result = asio::connect(socket, endpoints, true_cond_1, ec);
368   ASIO_CHECK(result == endpoints[0]);
369   ASIO_CHECK(!ec);
370 
371   result = asio::connect(socket, endpoints, true_cond_2(), ec);
372   ASIO_CHECK(result == endpoints[0]);
373   ASIO_CHECK(!ec);
374 
375   result = asio::connect(socket, endpoints, legacy_true_cond_1, ec);
376   ASIO_CHECK(result == endpoints[0]);
377   ASIO_CHECK(!ec);
378 
379   result = asio::connect(socket, endpoints, legacy_true_cond_2(), ec);
380   ASIO_CHECK(result == endpoints[0]);
381   ASIO_CHECK(!ec);
382 
383   result = asio::connect(socket, endpoints, false_cond, ec);
384   ASIO_CHECK(result == asio::ip::tcp::endpoint());
385   ASIO_CHECK(ec == asio::error::not_found);
386 
387   endpoints.push_back(sink.target_endpoint());
388 
389   result = asio::connect(socket, endpoints, true_cond_1, ec);
390   ASIO_CHECK(result == endpoints[0]);
391   ASIO_CHECK(!ec);
392 
393   result = asio::connect(socket, endpoints, true_cond_2(), ec);
394   ASIO_CHECK(result == endpoints[0]);
395   ASIO_CHECK(!ec);
396 
397   result = asio::connect(socket, endpoints, legacy_true_cond_1, ec);
398   ASIO_CHECK(result == endpoints[0]);
399   ASIO_CHECK(!ec);
400 
401   result = asio::connect(socket, endpoints, legacy_true_cond_2(), ec);
402   ASIO_CHECK(result == endpoints[0]);
403   ASIO_CHECK(!ec);
404 
405   result = asio::connect(socket, endpoints, false_cond, ec);
406   ASIO_CHECK(result == asio::ip::tcp::endpoint());
407   ASIO_CHECK(ec == asio::error::not_found);
408 
409   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
410 
411   result = asio::connect(socket, endpoints, true_cond_1, ec);
412   ASIO_CHECK(result == endpoints[1]);
413   ASIO_CHECK(!ec);
414 
415   result = asio::connect(socket, endpoints, true_cond_2(), ec);
416   ASIO_CHECK(result == endpoints[1]);
417   ASIO_CHECK(!ec);
418 
419   result = asio::connect(socket, endpoints, legacy_true_cond_1, ec);
420   ASIO_CHECK(result == endpoints[1]);
421   ASIO_CHECK(!ec);
422 
423   result = asio::connect(socket, endpoints, legacy_true_cond_2(), ec);
424   ASIO_CHECK(result == endpoints[1]);
425   ASIO_CHECK(!ec);
426 
427   result = asio::connect(socket, endpoints, false_cond, ec);
428   ASIO_CHECK(result == asio::ip::tcp::endpoint());
429   ASIO_CHECK(ec == asio::error::not_found);
430 }
431 
test_connect_iter()432 void test_connect_iter()
433 {
434   connection_sink sink;
435   asio::io_context io_context;
436   asio::ip::tcp::socket socket(io_context);
437   std::vector<asio::ip::tcp::endpoint> endpoints;
438   const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
439   std::vector<asio::ip::tcp::endpoint>::const_iterator result;
440 
441   try
442   {
443     result = asio::connect(socket, cendpoints.begin(), cendpoints.end());
444     ASIO_CHECK(false);
445   }
446   catch (asio::system_error& e)
447   {
448     ASIO_CHECK(e.code() == asio::error::not_found);
449   }
450 
451   endpoints.push_back(sink.target_endpoint());
452 
453   result = asio::connect(socket, cendpoints.begin(), cendpoints.end());
454   ASIO_CHECK(result == cendpoints.begin());
455 
456   endpoints.push_back(sink.target_endpoint());
457 
458   result = asio::connect(socket, cendpoints.begin(), cendpoints.end());
459   ASIO_CHECK(result == cendpoints.begin());
460 
461   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
462 
463   result = asio::connect(socket, cendpoints.begin(), cendpoints.end());
464   ASIO_CHECK(result == cendpoints.begin() + 1);
465 }
466 
test_connect_iter_ec()467 void test_connect_iter_ec()
468 {
469   connection_sink sink;
470   asio::io_context io_context;
471   asio::ip::tcp::socket socket(io_context);
472   std::vector<asio::ip::tcp::endpoint> endpoints;
473   const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
474   std::vector<asio::ip::tcp::endpoint>::const_iterator result;
475   asio::error_code ec;
476 
477   result = asio::connect(socket,
478       cendpoints.begin(), cendpoints.end(), ec);
479   ASIO_CHECK(result == cendpoints.end());
480   ASIO_CHECK(ec == asio::error::not_found);
481 
482   endpoints.push_back(sink.target_endpoint());
483 
484   result = asio::connect(socket,
485       cendpoints.begin(), cendpoints.end(), ec);
486   ASIO_CHECK(result == cendpoints.begin());
487   ASIO_CHECK(!ec);
488 
489   endpoints.push_back(sink.target_endpoint());
490 
491   result = asio::connect(socket,
492       cendpoints.begin(), cendpoints.end(), ec);
493   ASIO_CHECK(result == cendpoints.begin());
494   ASIO_CHECK(!ec);
495 
496   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
497 
498   result = asio::connect(socket,
499       cendpoints.begin(), cendpoints.end(), ec);
500   ASIO_CHECK(result == cendpoints.begin() + 1);
501   ASIO_CHECK(!ec);
502 }
503 
test_connect_iter_cond()504 void test_connect_iter_cond()
505 {
506   connection_sink sink;
507   asio::io_context io_context;
508   asio::ip::tcp::socket socket(io_context);
509   std::vector<asio::ip::tcp::endpoint> endpoints;
510   const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
511   std::vector<asio::ip::tcp::endpoint>::const_iterator result;
512 
513   try
514   {
515     result = asio::connect(socket, cendpoints.begin(),
516         cendpoints.end(), true_cond_1);
517     ASIO_CHECK(false);
518   }
519   catch (asio::system_error& e)
520   {
521     ASIO_CHECK(e.code() == asio::error::not_found);
522   }
523 
524   try
525   {
526     result = asio::connect(socket, cendpoints.begin(),
527         cendpoints.end(), true_cond_2());
528     ASIO_CHECK(false);
529   }
530   catch (asio::system_error& e)
531   {
532     ASIO_CHECK(e.code() == asio::error::not_found);
533   }
534 
535   try
536   {
537     result = asio::connect(socket, cendpoints.begin(),
538         cendpoints.end(), legacy_true_cond_1);
539     ASIO_CHECK(false);
540   }
541   catch (asio::system_error& e)
542   {
543     ASIO_CHECK(e.code() == asio::error::not_found);
544   }
545 
546   try
547   {
548     result = asio::connect(socket, cendpoints.begin(),
549         cendpoints.end(), legacy_true_cond_2());
550     ASIO_CHECK(false);
551   }
552   catch (asio::system_error& e)
553   {
554     ASIO_CHECK(e.code() == asio::error::not_found);
555   }
556 
557   try
558   {
559     result = asio::connect(socket, cendpoints.begin(),
560         cendpoints.end(), false_cond);
561     ASIO_CHECK(false);
562   }
563   catch (asio::system_error& e)
564   {
565     ASIO_CHECK(e.code() == asio::error::not_found);
566   }
567 
568   endpoints.push_back(sink.target_endpoint());
569 
570   result = asio::connect(socket, cendpoints.begin(),
571       cendpoints.end(), true_cond_1);
572   ASIO_CHECK(result == cendpoints.begin());
573 
574   result = asio::connect(socket, cendpoints.begin(),
575       cendpoints.end(), true_cond_2());
576   ASIO_CHECK(result == cendpoints.begin());
577 
578   result = asio::connect(socket, cendpoints.begin(),
579       cendpoints.end(), legacy_true_cond_1);
580   ASIO_CHECK(result == cendpoints.begin());
581 
582   result = asio::connect(socket, cendpoints.begin(),
583       cendpoints.end(), legacy_true_cond_2());
584   ASIO_CHECK(result == cendpoints.begin());
585 
586   try
587   {
588     result = asio::connect(socket, cendpoints.begin(),
589         cendpoints.end(), false_cond);
590     ASIO_CHECK(false);
591   }
592   catch (asio::system_error& e)
593   {
594     ASIO_CHECK(e.code() == asio::error::not_found);
595   }
596 
597   endpoints.push_back(sink.target_endpoint());
598 
599   result = asio::connect(socket, cendpoints.begin(),
600       cendpoints.end(), true_cond_1);
601   ASIO_CHECK(result == cendpoints.begin());
602 
603   result = asio::connect(socket, cendpoints.begin(),
604       cendpoints.end(), true_cond_2());
605   ASIO_CHECK(result == cendpoints.begin());
606 
607   result = asio::connect(socket, cendpoints.begin(),
608       cendpoints.end(), legacy_true_cond_1);
609   ASIO_CHECK(result == cendpoints.begin());
610 
611   result = asio::connect(socket, cendpoints.begin(),
612       cendpoints.end(), legacy_true_cond_2());
613   ASIO_CHECK(result == cendpoints.begin());
614 
615   try
616   {
617     result = asio::connect(socket, cendpoints.begin(),
618         cendpoints.end(), false_cond);
619     ASIO_CHECK(false);
620   }
621   catch (asio::system_error& e)
622   {
623     ASIO_CHECK(e.code() == asio::error::not_found);
624   }
625 
626   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
627 
628   result = asio::connect(socket, cendpoints.begin(),
629       cendpoints.end(), true_cond_1);
630   ASIO_CHECK(result == cendpoints.begin() + 1);
631 
632   result = asio::connect(socket, cendpoints.begin(),
633       cendpoints.end(), true_cond_2());
634   ASIO_CHECK(result == cendpoints.begin() + 1);
635 
636   result = asio::connect(socket, cendpoints.begin(),
637       cendpoints.end(), legacy_true_cond_1);
638   ASIO_CHECK(result == cendpoints.begin() + 1);
639 
640   result = asio::connect(socket, cendpoints.begin(),
641       cendpoints.end(), legacy_true_cond_2());
642   ASIO_CHECK(result == cendpoints.begin() + 1);
643 
644   try
645   {
646     result = asio::connect(socket, cendpoints.begin(),
647         cendpoints.end(), false_cond);
648     ASIO_CHECK(false);
649   }
650   catch (asio::system_error& e)
651   {
652     ASIO_CHECK(e.code() == 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   asio::io_context io_context;
660   asio::ip::tcp::socket socket(io_context);
661   std::vector<asio::ip::tcp::endpoint> endpoints;
662   const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
663   std::vector<asio::ip::tcp::endpoint>::const_iterator result;
664   asio::error_code ec;
665 
666   result = asio::connect(socket, cendpoints.begin(),
667       cendpoints.end(), true_cond_1, ec);
668   ASIO_CHECK(result == cendpoints.end());
669   ASIO_CHECK(ec == asio::error::not_found);
670 
671   result = asio::connect(socket, cendpoints.begin(),
672       cendpoints.end(), true_cond_2(), ec);
673   ASIO_CHECK(result == cendpoints.end());
674   ASIO_CHECK(ec == asio::error::not_found);
675 
676   result = asio::connect(socket, cendpoints.begin(),
677       cendpoints.end(), legacy_true_cond_1, ec);
678   ASIO_CHECK(result == cendpoints.end());
679   ASIO_CHECK(ec == asio::error::not_found);
680 
681   result = asio::connect(socket, cendpoints.begin(),
682       cendpoints.end(), legacy_true_cond_2(), ec);
683   ASIO_CHECK(result == cendpoints.end());
684   ASIO_CHECK(ec == asio::error::not_found);
685 
686   result = asio::connect(socket, cendpoints.begin(),
687       cendpoints.end(), false_cond, ec);
688   ASIO_CHECK(result == cendpoints.end());
689   ASIO_CHECK(ec == asio::error::not_found);
690 
691   endpoints.push_back(sink.target_endpoint());
692 
693   result = asio::connect(socket, cendpoints.begin(),
694       cendpoints.end(), true_cond_1, ec);
695   ASIO_CHECK(result == cendpoints.begin());
696   ASIO_CHECK(!ec);
697 
698   result = asio::connect(socket, cendpoints.begin(),
699       cendpoints.end(), true_cond_2(), ec);
700   ASIO_CHECK(result == cendpoints.begin());
701   ASIO_CHECK(!ec);
702 
703   result = asio::connect(socket, cendpoints.begin(),
704       cendpoints.end(), legacy_true_cond_1, ec);
705   ASIO_CHECK(result == cendpoints.begin());
706   ASIO_CHECK(!ec);
707 
708   result = asio::connect(socket, cendpoints.begin(),
709       cendpoints.end(), legacy_true_cond_2(), ec);
710   ASIO_CHECK(result == cendpoints.begin());
711   ASIO_CHECK(!ec);
712 
713   result = asio::connect(socket, cendpoints.begin(),
714       cendpoints.end(), false_cond, ec);
715   ASIO_CHECK(result == cendpoints.end());
716   ASIO_CHECK(ec == asio::error::not_found);
717 
718   endpoints.push_back(sink.target_endpoint());
719 
720   result = asio::connect(socket, cendpoints.begin(),
721       cendpoints.end(), true_cond_1, ec);
722   ASIO_CHECK(result == cendpoints.begin());
723   ASIO_CHECK(!ec);
724 
725   result = asio::connect(socket, cendpoints.begin(),
726       cendpoints.end(), true_cond_2(), ec);
727   ASIO_CHECK(result == cendpoints.begin());
728   ASIO_CHECK(!ec);
729 
730   result = asio::connect(socket, cendpoints.begin(),
731       cendpoints.end(), legacy_true_cond_1, ec);
732   ASIO_CHECK(result == cendpoints.begin());
733   ASIO_CHECK(!ec);
734 
735   result = asio::connect(socket, cendpoints.begin(),
736       cendpoints.end(), legacy_true_cond_2(), ec);
737   ASIO_CHECK(result == cendpoints.begin());
738   ASIO_CHECK(!ec);
739 
740   result = asio::connect(socket, cendpoints.begin(),
741       cendpoints.end(), false_cond, ec);
742   ASIO_CHECK(result == cendpoints.end());
743   ASIO_CHECK(ec == asio::error::not_found);
744 
745   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
746 
747   result = asio::connect(socket, cendpoints.begin(),
748       cendpoints.end(), true_cond_1, ec);
749   ASIO_CHECK(result == cendpoints.begin() + 1);
750   ASIO_CHECK(!ec);
751 
752   result = asio::connect(socket, cendpoints.begin(),
753       cendpoints.end(), true_cond_2(), ec);
754   ASIO_CHECK(result == cendpoints.begin() + 1);
755   ASIO_CHECK(!ec);
756 
757   result = asio::connect(socket, cendpoints.begin(),
758       cendpoints.end(), legacy_true_cond_1, ec);
759   ASIO_CHECK(result == cendpoints.begin() + 1);
760   ASIO_CHECK(!ec);
761 
762   result = asio::connect(socket, cendpoints.begin(),
763       cendpoints.end(), legacy_true_cond_2(), ec);
764   ASIO_CHECK(result == cendpoints.begin() + 1);
765   ASIO_CHECK(!ec);
766 
767   result = asio::connect(socket, cendpoints.begin(),
768       cendpoints.end(), false_cond, ec);
769   ASIO_CHECK(result == cendpoints.end());
770   ASIO_CHECK(ec == asio::error::not_found);
771 }
772 
test_async_connect_range()773 void test_async_connect_range()
774 {
775   connection_sink sink;
776   asio::io_context io_context;
777   asio::ip::tcp::socket socket(io_context);
778   std::vector<asio::ip::tcp::endpoint> endpoints;
779   asio::ip::tcp::endpoint result;
780   asio::error_code ec;
781 
782   asio::async_connect(socket, endpoints,
783       bindns::bind(range_handler, _1, _2, &ec, &result));
784   io_context.restart();
785   io_context.run();
786   ASIO_CHECK(result == asio::ip::tcp::endpoint());
787   ASIO_CHECK(ec == asio::error::not_found);
788 
789   endpoints.push_back(sink.target_endpoint());
790 
791   asio::async_connect(socket, endpoints,
792       bindns::bind(range_handler, _1, _2, &ec, &result));
793   io_context.restart();
794   io_context.run();
795   ASIO_CHECK(result == endpoints[0]);
796   ASIO_CHECK(!ec);
797 
798   endpoints.push_back(sink.target_endpoint());
799 
800   asio::async_connect(socket, endpoints,
801       bindns::bind(range_handler, _1, _2, &ec, &result));
802   io_context.restart();
803   io_context.run();
804   ASIO_CHECK(result == endpoints[0]);
805   ASIO_CHECK(!ec);
806 
807   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
808 
809   asio::async_connect(socket, endpoints,
810       bindns::bind(range_handler, _1, _2, &ec, &result));
811   io_context.restart();
812   io_context.run();
813   ASIO_CHECK(result == endpoints[1]);
814   ASIO_CHECK(!ec);
815 }
816 
test_async_connect_range_cond()817 void test_async_connect_range_cond()
818 {
819   connection_sink sink;
820   asio::io_context io_context;
821   asio::ip::tcp::socket socket(io_context);
822   std::vector<asio::ip::tcp::endpoint> endpoints;
823   asio::ip::tcp::endpoint result;
824   asio::error_code ec;
825 
826   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   ASIO_CHECK(result == asio::ip::tcp::endpoint());
831   ASIO_CHECK(ec == asio::error::not_found);
832 
833   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   ASIO_CHECK(result == asio::ip::tcp::endpoint());
838   ASIO_CHECK(ec == asio::error::not_found);
839 
840   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   ASIO_CHECK(result == asio::ip::tcp::endpoint());
845   ASIO_CHECK(ec == asio::error::not_found);
846 
847   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   ASIO_CHECK(result == asio::ip::tcp::endpoint());
852   ASIO_CHECK(ec == asio::error::not_found);
853 
854   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   ASIO_CHECK(result == asio::ip::tcp::endpoint());
859   ASIO_CHECK(ec == asio::error::not_found);
860 
861   endpoints.push_back(sink.target_endpoint());
862 
863   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   ASIO_CHECK(result == endpoints[0]);
868   ASIO_CHECK(!ec);
869 
870   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   ASIO_CHECK(result == endpoints[0]);
875   ASIO_CHECK(!ec);
876 
877   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   ASIO_CHECK(result == endpoints[0]);
882   ASIO_CHECK(!ec);
883 
884   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   ASIO_CHECK(result == endpoints[0]);
889   ASIO_CHECK(!ec);
890 
891   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   ASIO_CHECK(result == asio::ip::tcp::endpoint());
896   ASIO_CHECK(ec == asio::error::not_found);
897 
898   endpoints.push_back(sink.target_endpoint());
899 
900   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   ASIO_CHECK(result == endpoints[0]);
905   ASIO_CHECK(!ec);
906 
907   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   ASIO_CHECK(result == endpoints[0]);
912   ASIO_CHECK(!ec);
913 
914   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   ASIO_CHECK(result == endpoints[0]);
919   ASIO_CHECK(!ec);
920 
921   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   ASIO_CHECK(result == endpoints[0]);
926   ASIO_CHECK(!ec);
927 
928   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   ASIO_CHECK(result == asio::ip::tcp::endpoint());
933   ASIO_CHECK(ec == asio::error::not_found);
934 
935   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
936 
937   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   ASIO_CHECK(result == endpoints[1]);
942   ASIO_CHECK(!ec);
943 
944   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   ASIO_CHECK(result == endpoints[1]);
949   ASIO_CHECK(!ec);
950 
951   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   ASIO_CHECK(result == endpoints[1]);
956   ASIO_CHECK(!ec);
957 
958   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   ASIO_CHECK(result == endpoints[1]);
963   ASIO_CHECK(!ec);
964 
965   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   ASIO_CHECK(result == asio::ip::tcp::endpoint());
970   ASIO_CHECK(ec == asio::error::not_found);
971 }
972 
test_async_connect_iter()973 void test_async_connect_iter()
974 {
975   connection_sink sink;
976   asio::io_context io_context;
977   asio::ip::tcp::socket socket(io_context);
978   std::vector<asio::ip::tcp::endpoint> endpoints;
979   const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
980   std::vector<asio::ip::tcp::endpoint>::const_iterator result;
981   asio::error_code ec;
982 
983   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   ASIO_CHECK(result == cendpoints.end());
988   ASIO_CHECK(ec == asio::error::not_found);
989 
990   endpoints.push_back(sink.target_endpoint());
991 
992   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   ASIO_CHECK(result == cendpoints.begin());
997   ASIO_CHECK(!ec);
998 
999   endpoints.push_back(sink.target_endpoint());
1000 
1001   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   ASIO_CHECK(result == cendpoints.begin());
1006   ASIO_CHECK(!ec);
1007 
1008   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
1009 
1010   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   ASIO_CHECK(result == cendpoints.begin() + 1);
1015   ASIO_CHECK(!ec);
1016 }
1017 
test_async_connect_iter_cond()1018 void test_async_connect_iter_cond()
1019 {
1020   connection_sink sink;
1021   asio::io_context io_context;
1022   asio::ip::tcp::socket socket(io_context);
1023   std::vector<asio::ip::tcp::endpoint> endpoints;
1024   const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
1025   std::vector<asio::ip::tcp::endpoint>::const_iterator result;
1026   asio::error_code ec;
1027 
1028   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   ASIO_CHECK(result == cendpoints.end());
1033   ASIO_CHECK(ec == asio::error::not_found);
1034 
1035   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   ASIO_CHECK(result == cendpoints.end());
1040   ASIO_CHECK(ec == asio::error::not_found);
1041 
1042   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   ASIO_CHECK(result == cendpoints.end());
1047   ASIO_CHECK(ec == asio::error::not_found);
1048 
1049   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   ASIO_CHECK(result == cendpoints.end());
1054   ASIO_CHECK(ec == asio::error::not_found);
1055 
1056   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   ASIO_CHECK(result == cendpoints.end());
1061   ASIO_CHECK(ec == asio::error::not_found);
1062 
1063   endpoints.push_back(sink.target_endpoint());
1064 
1065   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   ASIO_CHECK(result == cendpoints.begin());
1070   ASIO_CHECK(!ec);
1071 
1072   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   ASIO_CHECK(result == cendpoints.begin());
1077   ASIO_CHECK(!ec);
1078 
1079   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   ASIO_CHECK(result == cendpoints.begin());
1084   ASIO_CHECK(!ec);
1085 
1086   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   ASIO_CHECK(result == cendpoints.begin());
1091   ASIO_CHECK(!ec);
1092 
1093   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   ASIO_CHECK(result == cendpoints.end());
1098   ASIO_CHECK(ec == asio::error::not_found);
1099 
1100   endpoints.push_back(sink.target_endpoint());
1101 
1102   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   ASIO_CHECK(result == cendpoints.begin());
1107   ASIO_CHECK(!ec);
1108 
1109   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   ASIO_CHECK(result == cendpoints.begin());
1114   ASIO_CHECK(!ec);
1115 
1116   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   ASIO_CHECK(result == cendpoints.begin());
1121   ASIO_CHECK(!ec);
1122 
1123   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   ASIO_CHECK(result == cendpoints.begin());
1128   ASIO_CHECK(!ec);
1129 
1130   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   ASIO_CHECK(result == cendpoints.end());
1135   ASIO_CHECK(ec == asio::error::not_found);
1136 
1137   endpoints.insert(endpoints.begin(), asio::ip::tcp::endpoint());
1138 
1139   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   ASIO_CHECK(result == cendpoints.begin() + 1);
1144   ASIO_CHECK(!ec);
1145 
1146   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   ASIO_CHECK(result == cendpoints.begin() + 1);
1151   ASIO_CHECK(!ec);
1152 
1153   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   ASIO_CHECK(result == cendpoints.begin() + 1);
1158   ASIO_CHECK(!ec);
1159 
1160   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   ASIO_CHECK(result == cendpoints.begin() + 1);
1165   ASIO_CHECK(!ec);
1166 
1167   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   ASIO_CHECK(result == cendpoints.end());
1172   ASIO_CHECK(ec == asio::error::not_found);
1173 }
1174 
1175 ASIO_TEST_SUITE
1176 (
1177   "connect",
1178   ASIO_TEST_CASE(test_connect_range)
1179   ASIO_TEST_CASE(test_connect_range_ec)
1180   ASIO_TEST_CASE(test_connect_range_cond)
1181   ASIO_TEST_CASE(test_connect_range_cond_ec)
1182   ASIO_TEST_CASE(test_connect_iter)
1183   ASIO_TEST_CASE(test_connect_iter_ec)
1184   ASIO_TEST_CASE(test_connect_iter_cond)
1185   ASIO_TEST_CASE(test_connect_iter_cond_ec)
1186   ASIO_TEST_CASE(test_async_connect_range)
1187   ASIO_TEST_CASE(test_async_connect_range_cond)
1188   ASIO_TEST_CASE(test_async_connect_iter)
1189   ASIO_TEST_CASE(test_async_connect_iter_cond)
1190 )
1191