connect.cpp 38 KB

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