Guest User

socket_ops.ipp

a guest
Dec 14th, 2014
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 98.92 KB | None | 0 0
  1. //
  2. // detail/impl/socket_ops.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2013 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. #ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_IPP
  12. #define BOOST_ASIO_DETAIL_SOCKET_OPS_IPP
  13.  
  14. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. # pragma once
  16. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  17.  
  18. #include <boost/asio/detail/config.hpp>
  19.  
  20. #include <cctype>
  21. #include <cstdio>
  22. #include <cstdlib>
  23. #include <cstring>
  24. #include <cerrno>
  25. #include <new>
  26. #include <boost/asio/detail/assert.hpp>
  27. #include <boost/asio/detail/socket_ops.hpp>
  28. #include <boost/asio/error.hpp>
  29.  
  30. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  31. # include <codecvt>
  32. # include <locale>
  33. # include <string>
  34. #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  35.  
  36. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) \
  37. || defined(__MACH__) && defined(__APPLE__)
  38. # if defined(BOOST_ASIO_HAS_PTHREADS)
  39. # include <pthread.h>
  40. # endif // defined(BOOST_ASIO_HAS_PTHREADS)
  41. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  42. // || defined(__MACH__) && defined(__APPLE__)
  43.  
  44. #include <boost/asio/detail/push_options.hpp>
  45.  
  46. namespace boost {
  47. namespace asio {
  48. namespace detail {
  49. namespace socket_ops {
  50.  
  51. #if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
  52.  
  53. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  54. struct msghdr { int msg_namelen; };
  55. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  56.  
  57. #if defined(__hpux)
  58. // HP-UX doesn't declare these functions extern "C", so they are declared again
  59. // here to avoid linker errors about undefined symbols.
  60. extern "C" char* if_indextoname(unsigned int, char*);
  61. extern "C" unsigned int if_nametoindex(const char*);
  62. #endif // defined(__hpux)
  63.  
  64. #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
  65.  
  66. inline void clear_last_error()
  67. {
  68. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  69. WSASetLastError(0);
  70. #else
  71. errno = 0;
  72. #endif
  73. }
  74.  
  75. #if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
  76.  
  77. template <typename ReturnType>
  78. inline ReturnType error_wrapper(ReturnType return_value,
  79. boost::system::error_code& ec)
  80. {
  81. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  82. ec = boost::system::error_code(WSAGetLastError(),
  83. boost::asio::error::get_system_category());
  84. #else
  85. ec = boost::system::error_code(errno,
  86. boost::asio::error::get_system_category());
  87. #endif
  88. return return_value;
  89. }
  90.  
  91. template <typename SockLenType>
  92. inline socket_type call_accept(SockLenType msghdr::*,
  93. socket_type s, socket_addr_type* addr, std::size_t* addrlen)
  94. {
  95. SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
  96. socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
  97. if (addrlen)
  98. *addrlen = (std::size_t)tmp_addrlen;
  99. return result;
  100. }
  101.  
  102. socket_type accept(socket_type s, socket_addr_type* addr,
  103. std::size_t* addrlen, boost::system::error_code& ec)
  104. {
  105. if (s == invalid_socket)
  106. {
  107. ec = boost::asio::error::bad_descriptor;
  108. return invalid_socket;
  109. }
  110.  
  111. clear_last_error();
  112.  
  113. socket_type new_s = error_wrapper(call_accept(
  114. &msghdr::msg_namelen, s, addr, addrlen), ec);
  115. if (new_s == invalid_socket)
  116. return new_s;
  117.  
  118. #if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
  119. int optval = 1;
  120. int result = error_wrapper(::setsockopt(new_s,
  121. SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
  122. if (result != 0)
  123. {
  124. ::close(new_s);
  125. return invalid_socket;
  126. }
  127. #endif
  128.  
  129. ec = boost::system::error_code();
  130. return new_s;
  131. }
  132.  
  133. socket_type sync_accept(socket_type s, state_type state,
  134. socket_addr_type* addr, std::size_t* addrlen, boost::system::error_code& ec)
  135. {
  136. // Accept a socket.
  137. for (;;)
  138. {
  139. // Try to complete the operation without blocking.
  140. socket_type new_socket = socket_ops::accept(s, addr, addrlen, ec);
  141.  
  142. // Check if operation succeeded.
  143. if (new_socket != invalid_socket)
  144. return new_socket;
  145.  
  146. // Operation failed.
  147. if (ec == boost::asio::error::would_block
  148. || ec == boost::asio::error::try_again)
  149. {
  150. if (state & user_set_non_blocking)
  151. return invalid_socket;
  152. // Fall through to retry operation.
  153. }
  154. else if (ec == boost::asio::error::connection_aborted)
  155. {
  156. if (state & enable_connection_aborted)
  157. return invalid_socket;
  158. // Fall through to retry operation.
  159. }
  160. #if defined(EPROTO)
  161. else if (ec.value() == EPROTO)
  162. {
  163. if (state & enable_connection_aborted)
  164. return invalid_socket;
  165. // Fall through to retry operation.
  166. }
  167. #endif // defined(EPROTO)
  168. else
  169. return invalid_socket;
  170.  
  171. // Wait for socket to become ready.
  172. if (socket_ops::poll_read(s, 0, ec) < 0)
  173. return invalid_socket;
  174. }
  175. }
  176.  
  177. #if defined(BOOST_ASIO_HAS_IOCP)
  178.  
  179. void complete_iocp_accept(socket_type s,
  180. void* output_buffer, DWORD address_length,
  181. socket_addr_type* addr, std::size_t* addrlen,
  182. socket_type new_socket, boost::system::error_code& ec)
  183. {
  184. // Map non-portable errors to their portable counterparts.
  185. if (ec.value() == ERROR_NETNAME_DELETED)
  186. ec = boost::asio::error::connection_aborted;
  187.  
  188. if (!ec)
  189. {
  190. // Get the address of the peer.
  191. if (addr && addrlen)
  192. {
  193. LPSOCKADDR local_addr = 0;
  194. int local_addr_length = 0;
  195. LPSOCKADDR remote_addr = 0;
  196. int remote_addr_length = 0;
  197. GetAcceptExSockaddrs(output_buffer, 0, address_length,
  198. address_length, &local_addr, &local_addr_length,
  199. &remote_addr, &remote_addr_length);
  200. if (static_cast<std::size_t>(remote_addr_length) > *addrlen)
  201. {
  202. ec = boost::asio::error::invalid_argument;
  203. }
  204. else
  205. {
  206. using namespace std; // For memcpy.
  207. memcpy(addr, remote_addr, remote_addr_length);
  208. *addrlen = static_cast<std::size_t>(remote_addr_length);
  209. }
  210. }
  211.  
  212. // Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname
  213. // and getpeername will work on the accepted socket.
  214. SOCKET update_ctx_param = s;
  215. socket_ops::state_type state = 0;
  216. socket_ops::setsockopt(new_socket, state,
  217. SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
  218. &update_ctx_param, sizeof(SOCKET), ec);
  219. }
  220. }
  221.  
  222. #else // defined(BOOST_ASIO_HAS_IOCP)
  223.  
  224. bool non_blocking_accept(socket_type s,
  225. state_type state, socket_addr_type* addr, std::size_t* addrlen,
  226. boost::system::error_code& ec, socket_type& new_socket)
  227. {
  228. for (;;)
  229. {
  230. // Accept the waiting connection.
  231. new_socket = socket_ops::accept(s, addr, addrlen, ec);
  232.  
  233. // Check if operation succeeded.
  234. if (new_socket != invalid_socket)
  235. return true;
  236.  
  237. // Retry operation if interrupted by signal.
  238. if (ec == boost::asio::error::interrupted)
  239. continue;
  240.  
  241. // Operation failed.
  242. if (ec == boost::asio::error::would_block
  243. || ec == boost::asio::error::try_again)
  244. {
  245. if (state & user_set_non_blocking)
  246. return true;
  247. // Fall through to retry operation.
  248. }
  249. else if (ec == boost::asio::error::connection_aborted)
  250. {
  251. if (state & enable_connection_aborted)
  252. return true;
  253. // Fall through to retry operation.
  254. }
  255. #if defined(EPROTO)
  256. else if (ec.value() == EPROTO)
  257. {
  258. if (state & enable_connection_aborted)
  259. return true;
  260. // Fall through to retry operation.
  261. }
  262. #endif // defined(EPROTO)
  263. else
  264. return true;
  265.  
  266. return false;
  267. }
  268. }
  269.  
  270. #endif // defined(BOOST_ASIO_HAS_IOCP)
  271.  
  272. template <typename SockLenType>
  273. inline int call_bind(SockLenType msghdr::*,
  274. socket_type s, const socket_addr_type* addr, std::size_t addrlen)
  275. {
  276. return ::bind(s, addr, (SockLenType)addrlen);
  277. }
  278.  
  279. int bind(socket_type s, const socket_addr_type* addr,
  280. std::size_t addrlen, boost::system::error_code& ec)
  281. {
  282. if (s == invalid_socket)
  283. {
  284. ec = boost::asio::error::bad_descriptor;
  285. return socket_error_retval;
  286. }
  287.  
  288. clear_last_error();
  289. int result = error_wrapper(call_bind(
  290. &msghdr::msg_namelen, s, addr, addrlen), ec);
  291. if (result == 0)
  292. ec = boost::system::error_code();
  293. return result;
  294. }
  295.  
  296. int close(socket_type s, state_type& state,
  297. bool destruction, boost::system::error_code& ec)
  298. {
  299. int result = 0;
  300. if (s != invalid_socket)
  301. {
  302. // We don't want the destructor to block, so set the socket to linger in
  303. // the background. If the user doesn't like this behaviour then they need
  304. // to explicitly close the socket.
  305. if (destruction && (state & user_set_linger))
  306. {
  307. ::linger opt;
  308. opt.l_onoff = 0;
  309. opt.l_linger = 0;
  310. boost::system::error_code ignored_ec;
  311. socket_ops::setsockopt(s, state, SOL_SOCKET,
  312. SO_LINGER, &opt, sizeof(opt), ignored_ec);
  313. }
  314.  
  315. clear_last_error();
  316. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  317. result = error_wrapper(::closesocket(s), ec);
  318. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  319. result = error_wrapper(::close(s), ec);
  320. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  321.  
  322. if (result != 0
  323. && (ec == boost::asio::error::would_block
  324. || ec == boost::asio::error::try_again))
  325. {
  326. // According to UNIX Network Programming Vol. 1, it is possible for
  327. // close() to fail with EWOULDBLOCK under certain circumstances. What
  328. // isn't clear is the state of the descriptor after this error. The one
  329. // current OS where this behaviour is seen, Windows, says that the socket
  330. // remains open. Therefore we'll put the descriptor back into blocking
  331. // mode and have another attempt at closing it.
  332. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  333. ioctl_arg_type arg = 0;
  334. ::ioctlsocket(s, FIONBIO, &arg);
  335. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  336. # if defined(__SYMBIAN32__)
  337. int flags = ::fcntl(s, F_GETFL, 0);
  338. if (flags >= 0)
  339. ::fcntl(s, F_SETFL, flags & ~O_NONBLOCK);
  340. # else // defined(__SYMBIAN32__)
  341. ioctl_arg_type arg = 0;
  342. ::ioctl(s, FIONBIO, &arg);
  343. # endif // defined(__SYMBIAN32__)
  344. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  345. state &= ~non_blocking;
  346.  
  347. clear_last_error();
  348. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  349. result = error_wrapper(::closesocket(s), ec);
  350. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  351. result = error_wrapper(::close(s), ec);
  352. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  353. }
  354. }
  355.  
  356. if (result == 0)
  357. ec = boost::system::error_code();
  358. return result;
  359. }
  360.  
  361. bool set_user_non_blocking(socket_type s,
  362. state_type& state, bool value, boost::system::error_code& ec)
  363. {
  364. if (s == invalid_socket)
  365. {
  366. ec = boost::asio::error::bad_descriptor;
  367. return false;
  368. }
  369.  
  370. clear_last_error();
  371. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  372. ioctl_arg_type arg = (value ? 1 : 0);
  373. int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec);
  374. #elif defined(__SYMBIAN32__)
  375. int result = error_wrapper(::fcntl(s, F_GETFL, 0), ec);
  376. if (result >= 0)
  377. {
  378. clear_last_error();
  379. int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
  380. result = error_wrapper(::fcntl(s, F_SETFL, flag), ec);
  381. }
  382. #else
  383. ioctl_arg_type arg = (value ? 1 : 0);
  384. int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
  385. #endif
  386.  
  387. if (result >= 0)
  388. {
  389. ec = boost::system::error_code();
  390. if (value)
  391. state |= user_set_non_blocking;
  392. else
  393. {
  394. // Clearing the user-set non-blocking mode always overrides any
  395. // internally-set non-blocking flag. Any subsequent asynchronous
  396. // operations will need to re-enable non-blocking I/O.
  397. state &= ~(user_set_non_blocking | internal_non_blocking);
  398. }
  399. return true;
  400. }
  401.  
  402. return false;
  403. }
  404.  
  405. bool set_internal_non_blocking(socket_type s,
  406. state_type& state, bool value, boost::system::error_code& ec)
  407. {
  408. if (s == invalid_socket)
  409. {
  410. ec = boost::asio::error::bad_descriptor;
  411. return false;
  412. }
  413.  
  414. if (!value && (state & user_set_non_blocking))
  415. {
  416. // It does not make sense to clear the internal non-blocking flag if the
  417. // user still wants non-blocking behaviour. Return an error and let the
  418. // caller figure out whether to update the user-set non-blocking flag.
  419. ec = boost::asio::error::invalid_argument;
  420. return false;
  421. }
  422.  
  423. clear_last_error();
  424. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  425. ioctl_arg_type arg = (value ? 1 : 0);
  426. int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec);
  427. #elif defined(__SYMBIAN32__)
  428. int result = error_wrapper(::fcntl(s, F_GETFL, 0), ec);
  429. if (result >= 0)
  430. {
  431. clear_last_error();
  432. int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
  433. result = error_wrapper(::fcntl(s, F_SETFL, flag), ec);
  434. }
  435. #else
  436. ioctl_arg_type arg = (value ? 1 : 0);
  437. int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
  438. #endif
  439.  
  440. if (result >= 0)
  441. {
  442. ec = boost::system::error_code();
  443. if (value)
  444. state |= internal_non_blocking;
  445. else
  446. state &= ~internal_non_blocking;
  447. return true;
  448. }
  449.  
  450. return false;
  451. }
  452.  
  453. int shutdown(socket_type s, int what, boost::system::error_code& ec)
  454. {
  455. if (s == invalid_socket)
  456. {
  457. ec = boost::asio::error::bad_descriptor;
  458. return socket_error_retval;
  459. }
  460.  
  461. clear_last_error();
  462. int result = error_wrapper(::shutdown(s, what), ec);
  463. if (result == 0)
  464. ec = boost::system::error_code();
  465. return result;
  466. }
  467.  
  468. template <typename SockLenType>
  469. inline int call_connect(SockLenType msghdr::*,
  470. socket_type s, const socket_addr_type* addr, std::size_t addrlen)
  471. {
  472. return ::connect(s, addr, (SockLenType)addrlen);
  473. }
  474.  
  475. int connect(socket_type s, const socket_addr_type* addr,
  476. std::size_t addrlen, boost::system::error_code& ec)
  477. {
  478. if (s == invalid_socket)
  479. {
  480. ec = boost::asio::error::bad_descriptor;
  481. return socket_error_retval;
  482. }
  483.  
  484. clear_last_error();
  485. int result = error_wrapper(call_connect(
  486. &msghdr::msg_namelen, s, addr, addrlen), ec);
  487. if (result == 0)
  488. ec = boost::system::error_code();
  489. #if defined(__linux__)
  490. else if (ec == boost::asio::error::try_again)
  491. ec = boost::asio::error::no_buffer_space;
  492. #endif // defined(__linux__)
  493. return result;
  494. }
  495.  
  496. void sync_connect(socket_type s, const socket_addr_type* addr,
  497. std::size_t addrlen, boost::system::error_code& ec)
  498. {
  499. // Perform the connect operation.
  500. socket_ops::connect(s, addr, addrlen, ec);
  501. if (ec != boost::asio::error::in_progress
  502. && ec != boost::asio::error::would_block)
  503. {
  504. // The connect operation finished immediately.
  505. return;
  506. }
  507.  
  508. // Wait for socket to become ready.
  509. if (socket_ops::poll_connect(s, ec) < 0)
  510. return;
  511.  
  512. // Get the error code from the connect operation.
  513. int connect_error = 0;
  514. size_t connect_error_len = sizeof(connect_error);
  515. if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
  516. &connect_error, &connect_error_len, ec) == socket_error_retval)
  517. return;
  518.  
  519. // Return the result of the connect operation.
  520. ec = boost::system::error_code(connect_error,
  521. boost::asio::error::get_system_category());
  522. }
  523.  
  524. bool non_blocking_connect(socket_type s, boost::system::error_code& ec)
  525. {
  526. // Check if the connect operation has finished. This is required since we may
  527. // get spurious readiness notifications from the reactor.
  528. #if defined(BOOST_ASIO_WINDOWS) \
  529. || defined(__CYGWIN__) \
  530. || defined(__SYMBIAN32__)
  531. fd_set write_fds;
  532. FD_ZERO(&write_fds);
  533. FD_SET(s, &write_fds);
  534. fd_set except_fds;
  535. FD_ZERO(&except_fds);
  536. FD_SET(s, &except_fds);
  537. timeval zero_timeout;
  538. zero_timeout.tv_sec = 0;
  539. zero_timeout.tv_usec = 0;
  540. int ready = ::select(s + 1, 0, &write_fds, &except_fds, &zero_timeout);
  541. #else // defined(BOOST_ASIO_WINDOWS)
  542. // || defined(__CYGWIN__)
  543. // || defined(__SYMBIAN32__)
  544. pollfd fds;
  545. fds.fd = s;
  546. fds.events = POLLOUT;
  547. fds.revents = 0;
  548. int ready = ::poll(&fds, 1, 0);
  549. #endif // defined(BOOST_ASIO_WINDOWS)
  550. // || defined(__CYGWIN__)
  551. // || defined(__SYMBIAN32__)
  552. if (ready == 0)
  553. {
  554. // The asynchronous connect operation is still in progress.
  555. return false;
  556. }
  557.  
  558. // Get the error code from the connect operation.
  559. int connect_error = 0;
  560. size_t connect_error_len = sizeof(connect_error);
  561. if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
  562. &connect_error, &connect_error_len, ec) == 0)
  563. {
  564. if (connect_error)
  565. {
  566. ec = boost::system::error_code(connect_error,
  567. boost::asio::error::get_system_category());
  568. }
  569. else
  570. ec = boost::system::error_code();
  571. }
  572.  
  573. return true;
  574. }
  575.  
  576. int socketpair(int af, int type, int protocol,
  577. socket_type sv[2], boost::system::error_code& ec)
  578. {
  579. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  580. (void)(af);
  581. (void)(type);
  582. (void)(protocol);
  583. (void)(sv);
  584. ec = boost::asio::error::operation_not_supported;
  585. return socket_error_retval;
  586. #else
  587. clear_last_error();
  588. int result = error_wrapper(::socketpair(af, type, protocol, sv), ec);
  589. if (result == 0)
  590. ec = boost::system::error_code();
  591. return result;
  592. #endif
  593. }
  594.  
  595. bool sockatmark(socket_type s, boost::system::error_code& ec)
  596. {
  597. if (s == invalid_socket)
  598. {
  599. ec = boost::asio::error::bad_descriptor;
  600. return false;
  601. }
  602.  
  603. #if defined(SIOCATMARK)
  604. ioctl_arg_type value = 0;
  605. # if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  606. int result = error_wrapper(::ioctlsocket(s, SIOCATMARK, &value), ec);
  607. # else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  608. int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec);
  609. # endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  610. if (result == 0)
  611. ec = boost::system::error_code();
  612. # if defined(ENOTTY)
  613. if (ec.value() == ENOTTY)
  614. ec = boost::asio::error::not_socket;
  615. # endif // defined(ENOTTY)
  616. #else // defined(SIOCATMARK)
  617. int value = error_wrapper(::sockatmark(s), ec);
  618. if (value != -1)
  619. ec = boost::system::error_code();
  620. #endif // defined(SIOCATMARK)
  621.  
  622. return ec ? false : value != 0;
  623. }
  624.  
  625. size_t available(socket_type s, boost::system::error_code& ec)
  626. {
  627. if (s == invalid_socket)
  628. {
  629. ec = boost::asio::error::bad_descriptor;
  630. return 0;
  631. }
  632.  
  633. ioctl_arg_type value = 0;
  634. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  635. int result = error_wrapper(::ioctlsocket(s, FIONREAD, &value), ec);
  636. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  637. int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec);
  638. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  639. if (result == 0)
  640. ec = boost::system::error_code();
  641. #if defined(ENOTTY)
  642. if (ec.value() == ENOTTY)
  643. ec = boost::asio::error::not_socket;
  644. #endif // defined(ENOTTY)
  645.  
  646. return ec ? static_cast<size_t>(0) : static_cast<size_t>(value);
  647. }
  648.  
  649. int listen(socket_type s, int backlog, boost::system::error_code& ec)
  650. {
  651. if (s == invalid_socket)
  652. {
  653. ec = boost::asio::error::bad_descriptor;
  654. return socket_error_retval;
  655. }
  656.  
  657. clear_last_error();
  658. int result = error_wrapper(::listen(s, backlog), ec);
  659. if (result == 0)
  660. ec = boost::system::error_code();
  661. return result;
  662. }
  663.  
  664. inline void init_buf_iov_base(void*& base, void* addr)
  665. {
  666. base = addr;
  667. }
  668.  
  669. template <typename T>
  670. inline void init_buf_iov_base(T& base, void* addr)
  671. {
  672. base = static_cast<T>(addr);
  673. }
  674.  
  675. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  676. typedef WSABUF buf;
  677. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  678. typedef iovec buf;
  679. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  680.  
  681. void init_buf(buf& b, void* data, size_t size)
  682. {
  683. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  684. b.buf = static_cast<char*>(data);
  685. b.len = static_cast<u_long>(size);
  686. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  687. init_buf_iov_base(b.iov_base, data);
  688. b.iov_len = size;
  689. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  690. }
  691.  
  692. void init_buf(buf& b, const void* data, size_t size)
  693. {
  694. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  695. b.buf = static_cast<char*>(const_cast<void*>(data));
  696. b.len = static_cast<u_long>(size);
  697. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  698. init_buf_iov_base(b.iov_base, const_cast<void*>(data));
  699. b.iov_len = size;
  700. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  701. }
  702.  
  703. inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
  704. {
  705. name = addr;
  706. }
  707.  
  708. inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
  709. {
  710. name = const_cast<socket_addr_type*>(addr);
  711. }
  712.  
  713. template <typename T>
  714. inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
  715. {
  716. name = reinterpret_cast<T>(addr);
  717. }
  718.  
  719. template <typename T>
  720. inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
  721. {
  722. name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
  723. }
  724.  
  725. signed_size_type recv(socket_type s, buf* bufs, size_t count,
  726. int flags, boost::system::error_code& ec)
  727. {
  728. clear_last_error();
  729. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  730. // Receive some data.
  731. DWORD recv_buf_count = static_cast<DWORD>(count);
  732. DWORD bytes_transferred = 0;
  733. DWORD recv_flags = flags;
  734. int result = error_wrapper(::WSARecv(s, bufs,
  735. recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);
  736. if (ec.value() == ERROR_NETNAME_DELETED)
  737. ec = boost::asio::error::connection_reset;
  738. else if (ec.value() == ERROR_PORT_UNREACHABLE)
  739. ec = boost::asio::error::connection_refused;
  740. if (result != 0)
  741. return socket_error_retval;
  742. ec = boost::system::error_code();
  743. return bytes_transferred;
  744. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  745. msghdr msg = msghdr();
  746. msg.msg_iov = bufs;
  747. msg.msg_iovlen = static_cast<int>(count);
  748. signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
  749. if (result >= 0)
  750. ec = boost::system::error_code();
  751. return result;
  752. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  753. }
  754.  
  755. size_t sync_recv(socket_type s, state_type state, buf* bufs,
  756. size_t count, int flags, bool all_empty, boost::system::error_code& ec)
  757. {
  758. if (s == invalid_socket)
  759. {
  760. ec = boost::asio::error::bad_descriptor;
  761. return 0;
  762. }
  763.  
  764. // A request to read 0 bytes on a stream is a no-op.
  765. if (all_empty && (state & stream_oriented))
  766. {
  767. ec = boost::system::error_code();
  768. return 0;
  769. }
  770.  
  771. // Read some data.
  772. for (;;)
  773. {
  774. // Try to complete the operation without blocking.
  775. signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);
  776.  
  777. // Check if operation succeeded.
  778. if (bytes > 0)
  779. return bytes;
  780.  
  781. // Check for EOF.
  782. if ((state & stream_oriented) && bytes == 0)
  783. {
  784. ec = boost::asio::error::eof;
  785. return 0;
  786. }
  787.  
  788. // Operation failed.
  789. if ((state & user_set_non_blocking)
  790. || (ec != boost::asio::error::would_block
  791. && ec != boost::asio::error::try_again))
  792. return 0;
  793.  
  794. // Wait for socket to become ready.
  795. if (socket_ops::poll_read(s, 0, ec) < 0)
  796. return 0;
  797. }
  798. }
  799.  
  800. #if defined(BOOST_ASIO_HAS_IOCP)
  801.  
  802. void complete_iocp_recv(state_type state,
  803. const weak_cancel_token_type& cancel_token, bool all_empty,
  804. boost::system::error_code& ec, size_t bytes_transferred)
  805. {
  806. // Map non-portable errors to their portable counterparts.
  807. if (ec.value() == ERROR_NETNAME_DELETED)
  808. {
  809. if (cancel_token.expired())
  810. ec = boost::asio::error::operation_aborted;
  811. else
  812. ec = boost::asio::error::connection_reset;
  813. }
  814. else if (ec.value() == ERROR_PORT_UNREACHABLE)
  815. {
  816. ec = boost::asio::error::connection_refused;
  817. }
  818.  
  819. // Check for connection closed.
  820. else if (!ec && bytes_transferred == 0
  821. && (state & stream_oriented) != 0
  822. && !all_empty)
  823. {
  824. ec = boost::asio::error::eof;
  825. }
  826. }
  827.  
  828. #else // defined(BOOST_ASIO_HAS_IOCP)
  829.  
  830. bool non_blocking_recv(socket_type s,
  831. buf* bufs, size_t count, int flags, bool is_stream,
  832. boost::system::error_code& ec, size_t& bytes_transferred)
  833. {
  834. for (;;)
  835. {
  836. // Read some data.
  837. signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);
  838.  
  839. // Check for end of stream.
  840. if (is_stream && bytes == 0)
  841. {
  842. ec = boost::asio::error::eof;
  843. return true;
  844. }
  845.  
  846. // Retry operation if interrupted by signal.
  847. if (ec == boost::asio::error::interrupted)
  848. continue;
  849.  
  850. // Check if we need to run the operation again.
  851. if (ec == boost::asio::error::would_block
  852. || ec == boost::asio::error::try_again)
  853. return false;
  854.  
  855. // Operation is complete.
  856. if (bytes >= 0)
  857. {
  858. ec = boost::system::error_code();
  859. bytes_transferred = bytes;
  860. }
  861. else
  862. bytes_transferred = 0;
  863.  
  864. return true;
  865. }
  866. }
  867.  
  868. #endif // defined(BOOST_ASIO_HAS_IOCP)
  869.  
  870. signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
  871. int flags, socket_addr_type* addr, std::size_t* addrlen,
  872. boost::system::error_code& ec)
  873. {
  874. clear_last_error();
  875. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  876. // Receive some data.
  877. DWORD recv_buf_count = static_cast<DWORD>(count);
  878. DWORD bytes_transferred = 0;
  879. DWORD recv_flags = flags;
  880. int tmp_addrlen = (int)*addrlen;
  881. int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
  882. &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec);
  883. *addrlen = (std::size_t)tmp_addrlen;
  884. if (ec.value() == ERROR_NETNAME_DELETED)
  885. ec = boost::asio::error::connection_reset;
  886. else if (ec.value() == ERROR_PORT_UNREACHABLE)
  887. ec = boost::asio::error::connection_refused;
  888. if (result != 0)
  889. return socket_error_retval;
  890. ec = boost::system::error_code();
  891. return bytes_transferred;
  892. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  893. msghdr msg = msghdr();
  894. init_msghdr_msg_name(msg.msg_name, addr);
  895. msg.msg_namelen = static_cast<int>(*addrlen);
  896. msg.msg_iov = bufs;
  897. msg.msg_iovlen = static_cast<int>(count);
  898. signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
  899. *addrlen = msg.msg_namelen;
  900. if (result >= 0)
  901. ec = boost::system::error_code();
  902. return result;
  903. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  904. }
  905.  
  906. size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
  907. size_t count, int flags, socket_addr_type* addr,
  908. std::size_t* addrlen, boost::system::error_code& ec)
  909. {
  910. if (s == invalid_socket)
  911. {
  912. ec = boost::asio::error::bad_descriptor;
  913. return 0;
  914. }
  915.  
  916. // Read some data.
  917. for (;;)
  918. {
  919. // Try to complete the operation without blocking.
  920. signed_size_type bytes = socket_ops::recvfrom(
  921. s, bufs, count, flags, addr, addrlen, ec);
  922.  
  923. // Check if operation succeeded.
  924. if (bytes >= 0)
  925. return bytes;
  926.  
  927. // Operation failed.
  928. if ((state & user_set_non_blocking)
  929. || (ec != boost::asio::error::would_block
  930. && ec != boost::asio::error::try_again))
  931. return 0;
  932.  
  933. // Wait for socket to become ready.
  934. if (socket_ops::poll_read(s, 0, ec) < 0)
  935. return 0;
  936. }
  937. }
  938.  
  939. #if defined(BOOST_ASIO_HAS_IOCP)
  940.  
  941. void complete_iocp_recvfrom(
  942. const weak_cancel_token_type& cancel_token,
  943. boost::system::error_code& ec)
  944. {
  945. // Map non-portable errors to their portable counterparts.
  946. if (ec.value() == ERROR_NETNAME_DELETED)
  947. {
  948. if (cancel_token.expired())
  949. ec = boost::asio::error::operation_aborted;
  950. else
  951. ec = boost::asio::error::connection_reset;
  952. }
  953. else if (ec.value() == ERROR_PORT_UNREACHABLE)
  954. {
  955. ec = boost::asio::error::connection_refused;
  956. }
  957. }
  958.  
  959. #else // defined(BOOST_ASIO_HAS_IOCP)
  960.  
  961. bool non_blocking_recvfrom(socket_type s,
  962. buf* bufs, size_t count, int flags,
  963. socket_addr_type* addr, std::size_t* addrlen,
  964. boost::system::error_code& ec, size_t& bytes_transferred)
  965. {
  966. for (;;)
  967. {
  968. // Read some data.
  969. signed_size_type bytes = socket_ops::recvfrom(
  970. s, bufs, count, flags, addr, addrlen, ec);
  971.  
  972. // Retry operation if interrupted by signal.
  973. if (ec == boost::asio::error::interrupted)
  974. continue;
  975.  
  976. // Check if we need to run the operation again.
  977. if (ec == boost::asio::error::would_block
  978. || ec == boost::asio::error::try_again)
  979. return false;
  980.  
  981. // Operation is complete.
  982. if (bytes >= 0)
  983. {
  984. ec = boost::system::error_code();
  985. bytes_transferred = bytes;
  986. }
  987. else
  988. bytes_transferred = 0;
  989.  
  990. return true;
  991. }
  992. }
  993.  
  994. #endif // defined(BOOST_ASIO_HAS_IOCP)
  995.  
  996. signed_size_type recvmsg(socket_type s, buf* bufs, size_t count,
  997. int in_flags, int& out_flags, boost::system::error_code& ec)
  998. {
  999. clear_last_error();
  1000. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1001. out_flags = 0;
  1002. return socket_ops::recv(s, bufs, count, in_flags, ec);
  1003. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1004. msghdr msg = msghdr();
  1005. msg.msg_iov = bufs;
  1006. msg.msg_iovlen = static_cast<int>(count);
  1007. signed_size_type result = error_wrapper(::recvmsg(s, &msg, in_flags), ec);
  1008. if (result >= 0)
  1009. {
  1010. ec = boost::system::error_code();
  1011. out_flags = msg.msg_flags;
  1012. }
  1013. else
  1014. out_flags = 0;
  1015. return result;
  1016. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1017. }
  1018.  
  1019. size_t sync_recvmsg(socket_type s, state_type state,
  1020. buf* bufs, size_t count, int in_flags, int& out_flags,
  1021. boost::system::error_code& ec)
  1022. {
  1023. if (s == invalid_socket)
  1024. {
  1025. ec = boost::asio::error::bad_descriptor;
  1026. return 0;
  1027. }
  1028.  
  1029. // Read some data.
  1030. for (;;)
  1031. {
  1032. // Try to complete the operation without blocking.
  1033. signed_size_type bytes = socket_ops::recvmsg(
  1034. s, bufs, count, in_flags, out_flags, ec);
  1035.  
  1036. // Check if operation succeeded.
  1037. if (bytes >= 0)
  1038. return bytes;
  1039.  
  1040. // Operation failed.
  1041. if ((state & user_set_non_blocking)
  1042. || (ec != boost::asio::error::would_block
  1043. && ec != boost::asio::error::try_again))
  1044. return 0;
  1045.  
  1046. // Wait for socket to become ready.
  1047. if (socket_ops::poll_read(s, 0, ec) < 0)
  1048. return 0;
  1049. }
  1050. }
  1051.  
  1052. #if defined(BOOST_ASIO_HAS_IOCP)
  1053.  
  1054. void complete_iocp_recvmsg(
  1055. const weak_cancel_token_type& cancel_token,
  1056. boost::system::error_code& ec)
  1057. {
  1058. // Map non-portable errors to their portable counterparts.
  1059. if (ec.value() == ERROR_NETNAME_DELETED)
  1060. {
  1061. if (cancel_token.expired())
  1062. ec = boost::asio::error::operation_aborted;
  1063. else
  1064. ec = boost::asio::error::connection_reset;
  1065. }
  1066. else if (ec.value() == ERROR_PORT_UNREACHABLE)
  1067. {
  1068. ec = boost::asio::error::connection_refused;
  1069. }
  1070. }
  1071.  
  1072. #else // defined(BOOST_ASIO_HAS_IOCP)
  1073.  
  1074. bool non_blocking_recvmsg(socket_type s,
  1075. buf* bufs, size_t count, int in_flags, int& out_flags,
  1076. boost::system::error_code& ec, size_t& bytes_transferred)
  1077. {
  1078. for (;;)
  1079. {
  1080. // Read some data.
  1081. signed_size_type bytes = socket_ops::recvmsg(
  1082. s, bufs, count, in_flags, out_flags, ec);
  1083.  
  1084. // Retry operation if interrupted by signal.
  1085. if (ec == boost::asio::error::interrupted)
  1086. continue;
  1087.  
  1088. // Check if we need to run the operation again.
  1089. if (ec == boost::asio::error::would_block
  1090. || ec == boost::asio::error::try_again)
  1091. return false;
  1092.  
  1093. // Operation is complete.
  1094. if (bytes >= 0)
  1095. {
  1096. ec = boost::system::error_code();
  1097. bytes_transferred = bytes;
  1098. }
  1099. else
  1100. bytes_transferred = 0;
  1101.  
  1102. return true;
  1103. }
  1104. }
  1105.  
  1106. #endif // defined(BOOST_ASIO_HAS_IOCP)
  1107.  
  1108. signed_size_type send(socket_type s, const buf* bufs, size_t count,
  1109. int flags, boost::system::error_code& ec)
  1110. {
  1111. clear_last_error();
  1112. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1113. // Send the data.
  1114. DWORD send_buf_count = static_cast<DWORD>(count);
  1115. DWORD bytes_transferred = 0;
  1116. DWORD send_flags = flags;
  1117. int result = error_wrapper(::WSASend(s, const_cast<buf*>(bufs),
  1118. send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);
  1119. if (ec.value() == ERROR_NETNAME_DELETED)
  1120. ec = boost::asio::error::connection_reset;
  1121. else if (ec.value() == ERROR_PORT_UNREACHABLE)
  1122. ec = boost::asio::error::connection_refused;
  1123. if (result != 0)
  1124. return socket_error_retval;
  1125. ec = boost::system::error_code();
  1126. return bytes_transferred;
  1127. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1128. msghdr msg = msghdr();
  1129. msg.msg_iov = const_cast<buf*>(bufs);
  1130. msg.msg_iovlen = static_cast<int>(count);
  1131. #if defined(__linux__)
  1132. flags |= MSG_NOSIGNAL;
  1133. #endif // defined(__linux__)
  1134. signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec);
  1135. if (result >= 0)
  1136. ec = boost::system::error_code();
  1137. return result;
  1138. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1139. }
  1140.  
  1141. size_t sync_send(socket_type s, state_type state, const buf* bufs,
  1142. size_t count, int flags, bool all_empty, boost::system::error_code& ec)
  1143. {
  1144. if (s == invalid_socket)
  1145. {
  1146. ec = boost::asio::error::bad_descriptor;
  1147. return 0;
  1148. }
  1149.  
  1150. // A request to write 0 bytes to a stream is a no-op.
  1151. if (all_empty && (state & stream_oriented))
  1152. {
  1153. ec = boost::system::error_code();
  1154. return 0;
  1155. }
  1156.  
  1157. // Read some data.
  1158. for (;;)
  1159. {
  1160. // Try to complete the operation without blocking.
  1161. signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec);
  1162.  
  1163. // Check if operation succeeded.
  1164. if (bytes >= 0)
  1165. return bytes;
  1166.  
  1167. // Operation failed.
  1168. if ((state & user_set_non_blocking)
  1169. || (ec != boost::asio::error::would_block
  1170. && ec != boost::asio::error::try_again))
  1171. return 0;
  1172.  
  1173. // Wait for socket to become ready.
  1174. if (socket_ops::poll_write(s, 0, ec) < 0)
  1175. return 0;
  1176. }
  1177. }
  1178.  
  1179. #if defined(BOOST_ASIO_HAS_IOCP)
  1180.  
  1181. void complete_iocp_send(
  1182. const weak_cancel_token_type& cancel_token,
  1183. boost::system::error_code& ec)
  1184. {
  1185. // Map non-portable errors to their portable counterparts.
  1186. if (ec.value() == ERROR_NETNAME_DELETED)
  1187. {
  1188. if (cancel_token.expired())
  1189. ec = boost::asio::error::operation_aborted;
  1190. else
  1191. ec = boost::asio::error::connection_reset;
  1192. }
  1193. else if (ec.value() == ERROR_PORT_UNREACHABLE)
  1194. {
  1195. ec = boost::asio::error::connection_refused;
  1196. }
  1197. }
  1198.  
  1199. #else // defined(BOOST_ASIO_HAS_IOCP)
  1200.  
  1201. bool non_blocking_send(socket_type s,
  1202. const buf* bufs, size_t count, int flags,
  1203. boost::system::error_code& ec, size_t& bytes_transferred)
  1204. {
  1205. for (;;)
  1206. {
  1207. // Write some data.
  1208. signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec);
  1209.  
  1210. // Retry operation if interrupted by signal.
  1211. if (ec == boost::asio::error::interrupted)
  1212. continue;
  1213.  
  1214. // Check if we need to run the operation again.
  1215. if (ec == boost::asio::error::would_block
  1216. || ec == boost::asio::error::try_again)
  1217. return false;
  1218.  
  1219. // Operation is complete.
  1220. if (bytes >= 0)
  1221. {
  1222. ec = boost::system::error_code();
  1223. bytes_transferred = bytes;
  1224. }
  1225. else
  1226. bytes_transferred = 0;
  1227.  
  1228. return true;
  1229. }
  1230. }
  1231.  
  1232. #endif // defined(BOOST_ASIO_HAS_IOCP)
  1233.  
  1234. signed_size_type sendto(socket_type s, const buf* bufs, size_t count,
  1235. int flags, const socket_addr_type* addr, std::size_t addrlen,
  1236. boost::system::error_code& ec)
  1237. {
  1238. clear_last_error();
  1239. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1240. // Send the data.
  1241. DWORD send_buf_count = static_cast<DWORD>(count);
  1242. DWORD bytes_transferred = 0;
  1243. int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),
  1244. send_buf_count, &bytes_transferred, flags, addr,
  1245. static_cast<int>(addrlen), 0, 0), ec);
  1246. if (ec.value() == ERROR_NETNAME_DELETED)
  1247. ec = boost::asio::error::connection_reset;
  1248. else if (ec.value() == ERROR_PORT_UNREACHABLE)
  1249. ec = boost::asio::error::connection_refused;
  1250. if (result != 0)
  1251. return socket_error_retval;
  1252. ec = boost::system::error_code();
  1253. return bytes_transferred;
  1254. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1255. msghdr msg = msghdr();
  1256. init_msghdr_msg_name(msg.msg_name, addr);
  1257. msg.msg_namelen = static_cast<int>(addrlen);
  1258. msg.msg_iov = const_cast<buf*>(bufs);
  1259. msg.msg_iovlen = static_cast<int>(count);
  1260. #if defined(__linux__)
  1261. flags |= MSG_NOSIGNAL;
  1262. #endif // defined(__linux__)
  1263. signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec);
  1264. if (result >= 0)
  1265. ec = boost::system::error_code();
  1266. return result;
  1267. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1268. }
  1269.  
  1270. size_t sync_sendto(socket_type s, state_type state, const buf* bufs,
  1271. size_t count, int flags, const socket_addr_type* addr,
  1272. std::size_t addrlen, boost::system::error_code& ec)
  1273. {
  1274. if (s == invalid_socket)
  1275. {
  1276. ec = boost::asio::error::bad_descriptor;
  1277. return 0;
  1278. }
  1279.  
  1280. // Write some data.
  1281. for (;;)
  1282. {
  1283. // Try to complete the operation without blocking.
  1284. signed_size_type bytes = socket_ops::sendto(
  1285. s, bufs, count, flags, addr, addrlen, ec);
  1286.  
  1287. // Check if operation succeeded.
  1288. if (bytes >= 0)
  1289. return bytes;
  1290.  
  1291. // Operation failed.
  1292. if ((state & user_set_non_blocking)
  1293. || (ec != boost::asio::error::would_block
  1294. && ec != boost::asio::error::try_again))
  1295. return 0;
  1296.  
  1297. // Wait for socket to become ready.
  1298. if (socket_ops::poll_write(s, 0, ec) < 0)
  1299. return 0;
  1300. }
  1301. }
  1302.  
  1303. #if !defined(BOOST_ASIO_HAS_IOCP)
  1304.  
  1305. bool non_blocking_sendto(socket_type s,
  1306. const buf* bufs, size_t count, int flags,
  1307. const socket_addr_type* addr, std::size_t addrlen,
  1308. boost::system::error_code& ec, size_t& bytes_transferred)
  1309. {
  1310. for (;;)
  1311. {
  1312. // Write some data.
  1313. signed_size_type bytes = socket_ops::sendto(
  1314. s, bufs, count, flags, addr, addrlen, ec);
  1315.  
  1316. // Retry operation if interrupted by signal.
  1317. if (ec == boost::asio::error::interrupted)
  1318. continue;
  1319.  
  1320. // Check if we need to run the operation again.
  1321. if (ec == boost::asio::error::would_block
  1322. || ec == boost::asio::error::try_again)
  1323. return false;
  1324.  
  1325. // Operation is complete.
  1326. if (bytes >= 0)
  1327. {
  1328. ec = boost::system::error_code();
  1329. bytes_transferred = bytes;
  1330. }
  1331. else
  1332. bytes_transferred = 0;
  1333.  
  1334. return true;
  1335. }
  1336. }
  1337.  
  1338. #endif // !defined(BOOST_ASIO_HAS_IOCP)
  1339.  
  1340. socket_type socket(int af, int type, int protocol,
  1341. boost::system::error_code& ec)
  1342. {
  1343. clear_last_error();
  1344. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1345. socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0,
  1346. WSA_FLAG_OVERLAPPED), ec);
  1347. if (s == invalid_socket)
  1348. return s;
  1349.  
  1350. if (af == BOOST_ASIO_OS_DEF(AF_INET6))
  1351. {
  1352. // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to
  1353. // false. This will only succeed on Windows Vista and later versions of
  1354. // Windows, where a dual-stack IPv4/v6 implementation is available.
  1355. DWORD optval = 0;
  1356. ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
  1357. reinterpret_cast<const char*>(&optval), sizeof(optval));
  1358. }
  1359.  
  1360. ec = boost::system::error_code();
  1361.  
  1362. return s;
  1363. #elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
  1364. socket_type s = error_wrapper(::socket(af, type, protocol), ec);
  1365. if (s == invalid_socket)
  1366. return s;
  1367.  
  1368. int optval = 1;
  1369. int result = error_wrapper(::setsockopt(s,
  1370. SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
  1371. if (result != 0)
  1372. {
  1373. ::close(s);
  1374. return invalid_socket;
  1375. }
  1376.  
  1377. return s;
  1378. #else
  1379. int s = error_wrapper(::socket(af, type, protocol), ec);
  1380. if (s >= 0)
  1381. ec = boost::system::error_code();
  1382. return s;
  1383. #endif
  1384. }
  1385.  
  1386. template <typename SockLenType>
  1387. inline int call_setsockopt(SockLenType msghdr::*,
  1388. socket_type s, int level, int optname,
  1389. const void* optval, std::size_t optlen)
  1390. {
  1391. return ::setsockopt(s, level, optname,
  1392. (const char*)optval, (SockLenType)optlen);
  1393. }
  1394.  
  1395. int setsockopt(socket_type s, state_type& state, int level, int optname,
  1396. const void* optval, std::size_t optlen, boost::system::error_code& ec)
  1397. {
  1398. if (s == invalid_socket)
  1399. {
  1400. ec = boost::asio::error::bad_descriptor;
  1401. return socket_error_retval;
  1402. }
  1403.  
  1404. if (level == custom_socket_option_level && optname == always_fail_option)
  1405. {
  1406. ec = boost::asio::error::invalid_argument;
  1407. return socket_error_retval;
  1408. }
  1409.  
  1410. if (level == custom_socket_option_level
  1411. && optname == enable_connection_aborted_option)
  1412. {
  1413. if (optlen != sizeof(int))
  1414. {
  1415. ec = boost::asio::error::invalid_argument;
  1416. return socket_error_retval;
  1417. }
  1418.  
  1419. if (*static_cast<const int*>(optval))
  1420. state |= enable_connection_aborted;
  1421. else
  1422. state &= ~enable_connection_aborted;
  1423. ec = boost::system::error_code();
  1424. return 0;
  1425. }
  1426.  
  1427. if (level == SOL_SOCKET && optname == SO_LINGER)
  1428. state |= user_set_linger;
  1429.  
  1430. #if defined(__BORLANDC__)
  1431. // Mysteriously, using the getsockopt and setsockopt functions directly with
  1432. // Borland C++ results in incorrect values being set and read. The bug can be
  1433. // worked around by using function addresses resolved with GetProcAddress.
  1434. if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
  1435. {
  1436. typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int);
  1437. if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt"))
  1438. {
  1439. clear_last_error();
  1440. return error_wrapper(sso(s, level, optname,
  1441. reinterpret_cast<const char*>(optval),
  1442. static_cast<int>(optlen)), ec);
  1443. }
  1444. }
  1445. ec = boost::asio::error::fault;
  1446. return socket_error_retval;
  1447. #else // defined(__BORLANDC__)
  1448. clear_last_error();
  1449. int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
  1450. s, level, optname, optval, optlen), ec);
  1451. if (result == 0)
  1452. {
  1453. ec = boost::system::error_code();
  1454.  
  1455. #if defined(__MACH__) && defined(__APPLE__) \
  1456. || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
  1457. // To implement portable behaviour for SO_REUSEADDR with UDP sockets we
  1458. // need to also set SO_REUSEPORT on BSD-based platforms.
  1459. if ((state & datagram_oriented)
  1460. && level == SOL_SOCKET && optname == SO_REUSEADDR)
  1461. {
  1462. call_setsockopt(&msghdr::msg_namelen, s,
  1463. SOL_SOCKET, SO_REUSEPORT, optval, optlen);
  1464. }
  1465. #endif
  1466. }
  1467.  
  1468. return result;
  1469. #endif // defined(__BORLANDC__)
  1470. }
  1471.  
  1472. template <typename SockLenType>
  1473. inline int call_getsockopt(SockLenType msghdr::*,
  1474. socket_type s, int level, int optname,
  1475. void* optval, std::size_t* optlen)
  1476. {
  1477. SockLenType tmp_optlen = (SockLenType)*optlen;
  1478. int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
  1479. *optlen = (std::size_t)tmp_optlen;
  1480. return result;
  1481. }
  1482.  
  1483. int getsockopt(socket_type s, state_type state, int level, int optname,
  1484. void* optval, size_t* optlen, boost::system::error_code& ec)
  1485. {
  1486. if (s == invalid_socket)
  1487. {
  1488. ec = boost::asio::error::bad_descriptor;
  1489. return socket_error_retval;
  1490. }
  1491.  
  1492. if (level == custom_socket_option_level && optname == always_fail_option)
  1493. {
  1494. ec = boost::asio::error::invalid_argument;
  1495. return socket_error_retval;
  1496. }
  1497.  
  1498. if (level == custom_socket_option_level
  1499. && optname == enable_connection_aborted_option)
  1500. {
  1501. if (*optlen != sizeof(int))
  1502. {
  1503. ec = boost::asio::error::invalid_argument;
  1504. return socket_error_retval;
  1505. }
  1506.  
  1507. *static_cast<int*>(optval) = (state & enable_connection_aborted) ? 1 : 0;
  1508. ec = boost::system::error_code();
  1509. return 0;
  1510. }
  1511.  
  1512. #if defined(__BORLANDC__)
  1513. // Mysteriously, using the getsockopt and setsockopt functions directly with
  1514. // Borland C++ results in incorrect values being set and read. The bug can be
  1515. // worked around by using function addresses resolved with GetProcAddress.
  1516. if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
  1517. {
  1518. typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*);
  1519. if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt"))
  1520. {
  1521. clear_last_error();
  1522. int tmp_optlen = static_cast<int>(*optlen);
  1523. int result = error_wrapper(gso(s, level, optname,
  1524. reinterpret_cast<char*>(optval), &tmp_optlen), ec);
  1525. *optlen = static_cast<size_t>(tmp_optlen);
  1526. if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
  1527. && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
  1528. {
  1529. // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are
  1530. // only supported on Windows Vista and later. To simplify program logic
  1531. // we will fake success of getting this option and specify that the
  1532. // value is non-zero (i.e. true). This corresponds to the behavior of
  1533. // IPv6 sockets on Windows platforms pre-Vista.
  1534. *static_cast<DWORD*>(optval) = 1;
  1535. ec = boost::system::error_code();
  1536. }
  1537. return result;
  1538. }
  1539. }
  1540. ec = boost::asio::error::fault;
  1541. return socket_error_retval;
  1542. #elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1543. clear_last_error();
  1544. int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
  1545. s, level, optname, optval, optlen), ec);
  1546. if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
  1547. && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
  1548. {
  1549. // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only
  1550. // supported on Windows Vista and later. To simplify program logic we will
  1551. // fake success of getting this option and specify that the value is
  1552. // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets
  1553. // on Windows platforms pre-Vista.
  1554. *static_cast<DWORD*>(optval) = 1;
  1555. ec = boost::system::error_code();
  1556. }
  1557. if (result == 0)
  1558. ec = boost::system::error_code();
  1559. return result;
  1560. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1561. clear_last_error();
  1562. int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
  1563. s, level, optname, optval, optlen), ec);
  1564. #if defined(__linux__)
  1565. if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
  1566. && (optname == SO_SNDBUF || optname == SO_RCVBUF))
  1567. {
  1568. // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel
  1569. // to set the buffer size to N*2. Linux puts additional stuff into the
  1570. // buffers so that only about half is actually available to the application.
  1571. // The retrieved value is divided by 2 here to make it appear as though the
  1572. // correct value has been set.
  1573. *static_cast<int*>(optval) /= 2;
  1574. }
  1575. #endif // defined(__linux__)
  1576. if (result == 0)
  1577. ec = boost::system::error_code();
  1578. return result;
  1579. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1580. }
  1581.  
  1582. template <typename SockLenType>
  1583. inline int call_getpeername(SockLenType msghdr::*,
  1584. socket_type s, socket_addr_type* addr, std::size_t* addrlen)
  1585. {
  1586. SockLenType tmp_addrlen = (SockLenType)*addrlen;
  1587. int result = ::getpeername(s, addr, &tmp_addrlen);
  1588. *addrlen = (std::size_t)tmp_addrlen;
  1589. return result;
  1590. }
  1591.  
  1592. int getpeername(socket_type s, socket_addr_type* addr,
  1593. std::size_t* addrlen, bool cached, boost::system::error_code& ec)
  1594. {
  1595. if (s == invalid_socket)
  1596. {
  1597. ec = boost::asio::error::bad_descriptor;
  1598. return socket_error_retval;
  1599. }
  1600.  
  1601. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1602. if (cached)
  1603. {
  1604. // Check if socket is still connected.
  1605. DWORD connect_time = 0;
  1606. size_t connect_time_len = sizeof(connect_time);
  1607. if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_CONNECT_TIME,
  1608. &connect_time, &connect_time_len, ec) == socket_error_retval)
  1609. {
  1610. return socket_error_retval;
  1611. }
  1612. if (connect_time == 0xFFFFFFFF)
  1613. {
  1614. ec = boost::asio::error::not_connected;
  1615. return socket_error_retval;
  1616. }
  1617.  
  1618. // The cached value is still valid.
  1619. ec = boost::system::error_code();
  1620. return 0;
  1621. }
  1622. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1623. (void)cached;
  1624. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1625.  
  1626. clear_last_error();
  1627. int result = error_wrapper(call_getpeername(
  1628. &msghdr::msg_namelen, s, addr, addrlen), ec);
  1629. if (result == 0)
  1630. ec = boost::system::error_code();
  1631. return result;
  1632. }
  1633.  
  1634. template <typename SockLenType>
  1635. inline int call_getsockname(SockLenType msghdr::*,
  1636. socket_type s, socket_addr_type* addr, std::size_t* addrlen)
  1637. {
  1638. SockLenType tmp_addrlen = (SockLenType)*addrlen;
  1639. int result = ::getsockname(s, addr, &tmp_addrlen);
  1640. *addrlen = (std::size_t)tmp_addrlen;
  1641. return result;
  1642. }
  1643.  
  1644. int getsockname(socket_type s, socket_addr_type* addr,
  1645. std::size_t* addrlen, boost::system::error_code& ec)
  1646. {
  1647. if (s == invalid_socket)
  1648. {
  1649. ec = boost::asio::error::bad_descriptor;
  1650. return socket_error_retval;
  1651. }
  1652.  
  1653. clear_last_error();
  1654. int result = error_wrapper(call_getsockname(
  1655. &msghdr::msg_namelen, s, addr, addrlen), ec);
  1656. if (result == 0)
  1657. ec = boost::system::error_code();
  1658. return result;
  1659. }
  1660.  
  1661. int ioctl(socket_type s, state_type& state, int cmd,
  1662. ioctl_arg_type* arg, boost::system::error_code& ec)
  1663. {
  1664. if (s == invalid_socket)
  1665. {
  1666. ec = boost::asio::error::bad_descriptor;
  1667. return socket_error_retval;
  1668. }
  1669.  
  1670. clear_last_error();
  1671. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1672. int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec);
  1673. #elif defined(__MACH__) && defined(__APPLE__) \
  1674. || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
  1675. int result = error_wrapper(::ioctl(s,
  1676. static_cast<unsigned int>(cmd), arg), ec);
  1677. #else
  1678. int result = error_wrapper(::ioctl(s, cmd, arg), ec);
  1679. #endif
  1680. if (result >= 0)
  1681. {
  1682. ec = boost::system::error_code();
  1683.  
  1684. // When updating the non-blocking mode we always perform the ioctl syscall,
  1685. // even if the flags would otherwise indicate that the socket is already in
  1686. // the correct state. This ensures that the underlying socket is put into
  1687. // the state that has been requested by the user. If the ioctl syscall was
  1688. // successful then we need to update the flags to match.
  1689. if (cmd == static_cast<int>(FIONBIO))
  1690. {
  1691. if (*arg)
  1692. {
  1693. state |= user_set_non_blocking;
  1694. }
  1695. else
  1696. {
  1697. // Clearing the non-blocking mode always overrides any internally-set
  1698. // non-blocking flag. Any subsequent asynchronous operations will need
  1699. // to re-enable non-blocking I/O.
  1700. state &= ~(user_set_non_blocking | internal_non_blocking);
  1701. }
  1702. }
  1703. }
  1704.  
  1705. return result;
  1706. }
  1707.  
  1708. int select(int nfds, fd_set* readfds, fd_set* writefds,
  1709. fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec)
  1710. {
  1711. clear_last_error();
  1712. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1713. if (!readfds && !writefds && !exceptfds && timeout)
  1714. {
  1715. DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
  1716. if (milliseconds == 0)
  1717. milliseconds = 1; // Force context switch.
  1718. ::Sleep(milliseconds);
  1719. ec = boost::system::error_code();
  1720. return 0;
  1721. }
  1722.  
  1723. // The select() call allows timeout values measured in microseconds, but the
  1724. // system clock (as wrapped by boost::posix_time::microsec_clock) typically
  1725. // has a resolution of 10 milliseconds. This can lead to a spinning select
  1726. // reactor, meaning increased CPU usage, when waiting for the earliest
  1727. // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight
  1728. // spin we'll use a minimum timeout of 1 millisecond.
  1729. if (timeout && timeout->tv_sec == 0
  1730. && timeout->tv_usec > 0 && timeout->tv_usec < 1000)
  1731. timeout->tv_usec = 1000;
  1732. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1733.  
  1734. #if defined(__hpux) && defined(__SELECT)
  1735. timespec ts;
  1736. ts.tv_sec = timeout ? timeout->tv_sec : 0;
  1737. ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
  1738. return error_wrapper(::pselect(nfds, readfds,
  1739. writefds, exceptfds, timeout ? &ts : 0, 0), ec);
  1740. #else
  1741. int result = error_wrapper(::select(nfds, readfds,
  1742. writefds, exceptfds, timeout), ec);
  1743. if (result >= 0)
  1744. ec = boost::system::error_code();
  1745. return result;
  1746. #endif
  1747. }
  1748.  
  1749. int poll_read(socket_type s, state_type state, boost::system::error_code& ec)
  1750. {
  1751. if (s == invalid_socket)
  1752. {
  1753. ec = boost::asio::error::bad_descriptor;
  1754. return socket_error_retval;
  1755. }
  1756.  
  1757. #if defined(BOOST_ASIO_WINDOWS) \
  1758. || defined(__CYGWIN__) \
  1759. || defined(__SYMBIAN32__)
  1760. fd_set fds;
  1761. FD_ZERO(&fds);
  1762. FD_SET(s, &fds);
  1763. timeval zero_timeout;
  1764. zero_timeout.tv_sec = 0;
  1765. zero_timeout.tv_usec = 0;
  1766. timeval* timeout = (state & user_set_non_blocking) ? &zero_timeout : 0;
  1767. clear_last_error();
  1768. int result = error_wrapper(::select(s + 1, &fds, 0, 0, timeout), ec);
  1769. #else // defined(BOOST_ASIO_WINDOWS)
  1770. // || defined(__CYGWIN__)
  1771. // || defined(__SYMBIAN32__)
  1772. pollfd fds;
  1773. fds.fd = s;
  1774. fds.events = POLLIN;
  1775. fds.revents = 0;
  1776. int timeout = (state & user_set_non_blocking) ? 0 : -1;
  1777. clear_last_error();
  1778. int result = error_wrapper(::poll(&fds, 1, timeout), ec);
  1779. #endif // defined(BOOST_ASIO_WINDOWS)
  1780. // || defined(__CYGWIN__)
  1781. // || defined(__SYMBIAN32__)
  1782. if (result == 0)
  1783. ec = (state & user_set_non_blocking)
  1784. ? boost::asio::error::would_block : boost::system::error_code();
  1785. else if (result > 0)
  1786. ec = boost::system::error_code();
  1787. return result;
  1788. }
  1789.  
  1790. int poll_write(socket_type s, state_type state, boost::system::error_code& ec)
  1791. {
  1792. if (s == invalid_socket)
  1793. {
  1794. ec = boost::asio::error::bad_descriptor;
  1795. return socket_error_retval;
  1796. }
  1797.  
  1798. #if defined(BOOST_ASIO_WINDOWS) \
  1799. || defined(__CYGWIN__) \
  1800. || defined(__SYMBIAN32__)
  1801. fd_set fds;
  1802. FD_ZERO(&fds);
  1803. FD_SET(s, &fds);
  1804. timeval zero_timeout;
  1805. zero_timeout.tv_sec = 0;
  1806. zero_timeout.tv_usec = 0;
  1807. timeval* timeout = (state & user_set_non_blocking) ? &zero_timeout : 0;
  1808. clear_last_error();
  1809. int result = error_wrapper(::select(s + 1, 0, &fds, 0, timeout), ec);
  1810. #else // defined(BOOST_ASIO_WINDOWS)
  1811. // || defined(__CYGWIN__)
  1812. // || defined(__SYMBIAN32__)
  1813. pollfd fds;
  1814. fds.fd = s;
  1815. fds.events = POLLOUT;
  1816. fds.revents = 0;
  1817. int timeout = (state & user_set_non_blocking) ? 0 : -1;
  1818. clear_last_error();
  1819. int result = error_wrapper(::poll(&fds, 1, timeout), ec);
  1820. #endif // defined(BOOST_ASIO_WINDOWS)
  1821. // || defined(__CYGWIN__)
  1822. // || defined(__SYMBIAN32__)
  1823. if (result == 0)
  1824. ec = (state & user_set_non_blocking)
  1825. ? boost::asio::error::would_block : boost::system::error_code();
  1826. else if (result > 0)
  1827. ec = boost::system::error_code();
  1828. return result;
  1829. }
  1830.  
  1831. int poll_connect(socket_type s, boost::system::error_code& ec)
  1832. {
  1833. if (s == invalid_socket)
  1834. {
  1835. ec = boost::asio::error::bad_descriptor;
  1836. return socket_error_retval;
  1837. }
  1838.  
  1839. #if defined(BOOST_ASIO_WINDOWS) \
  1840. || defined(__CYGWIN__) \
  1841. || defined(__SYMBIAN32__)
  1842. fd_set write_fds;
  1843. FD_ZERO(&write_fds);
  1844. FD_SET(s, &write_fds);
  1845. fd_set except_fds;
  1846. FD_ZERO(&except_fds);
  1847. FD_SET(s, &except_fds);
  1848. clear_last_error();
  1849. int result = error_wrapper(::select(
  1850. s + 1, 0, &write_fds, &except_fds, 0), ec);
  1851. if (result >= 0)
  1852. ec = boost::system::error_code();
  1853. return result;
  1854. #else // defined(BOOST_ASIO_WINDOWS)
  1855. // || defined(__CYGWIN__)
  1856. // || defined(__SYMBIAN32__)
  1857. pollfd fds;
  1858. fds.fd = s;
  1859. fds.events = POLLOUT;
  1860. fds.revents = 0;
  1861. clear_last_error();
  1862. int result = error_wrapper(::poll(&fds, 1, -1), ec);
  1863. if (result >= 0)
  1864. ec = boost::system::error_code();
  1865. return result;
  1866. #endif // defined(BOOST_ASIO_WINDOWS)
  1867. // || defined(__CYGWIN__)
  1868. // || defined(__SYMBIAN32__)
  1869. }
  1870.  
  1871. #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
  1872.  
  1873. const char* inet_ntop(int af, const void* src, char* dest, size_t length,
  1874. unsigned long scope_id, boost::system::error_code& ec)
  1875. {
  1876. clear_last_error();
  1877. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  1878. using namespace std; // For sprintf.
  1879. const unsigned char* bytes = static_cast<const unsigned char*>(src);
  1880. if (af == BOOST_ASIO_OS_DEF(AF_INET))
  1881. {
  1882. sprintf_s(dest, length, "%u.%u.%u.%u",
  1883. bytes[0], bytes[1], bytes[2], bytes[3]);
  1884. return dest;
  1885. }
  1886. else if (af == BOOST_ASIO_OS_DEF(AF_INET6))
  1887. {
  1888. size_t n = 0, b = 0, z = 0;
  1889. while (n < length && b < 16)
  1890. {
  1891. if (bytes[b] == 0 && bytes[b + 1] == 0 && z == 0)
  1892. {
  1893. do b += 2; while (b < 16 && bytes[b] == 0 && bytes[b + 1] == 0);
  1894. n += sprintf_s(dest + n, length - n, ":%s", b < 16 ? "" : ":"), ++z;
  1895. }
  1896. else
  1897. {
  1898. n += sprintf_s(dest + n, length - n, "%s%x", b ? ":" : "",
  1899. (static_cast<u_long_type>(bytes[b]) << 8) | bytes[b + 1]);
  1900. b += 2;
  1901. }
  1902. }
  1903. if (scope_id)
  1904. n += sprintf_s(dest + n, length - n, "%%%lu", scope_id);
  1905. return dest;
  1906. }
  1907. else
  1908. {
  1909. ec = boost::asio::error::address_family_not_supported;
  1910. return 0;
  1911. }
  1912. #elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1913. using namespace std; // For memcpy.
  1914.  
  1915. if (af != BOOST_ASIO_OS_DEF(AF_INET) && af != BOOST_ASIO_OS_DEF(AF_INET6))
  1916. {
  1917. ec = boost::asio::error::address_family_not_supported;
  1918. return 0;
  1919. }
  1920.  
  1921. union
  1922. {
  1923. socket_addr_type base;
  1924. sockaddr_storage_type storage;
  1925. sockaddr_in4_type v4;
  1926. sockaddr_in6_type v6;
  1927. } address;
  1928. DWORD address_length;
  1929. if (af == BOOST_ASIO_OS_DEF(AF_INET))
  1930. {
  1931. address_length = sizeof(sockaddr_in4_type);
  1932. address.v4.sin_family = BOOST_ASIO_OS_DEF(AF_INET);
  1933. address.v4.sin_port = 0;
  1934. memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type));
  1935. }
  1936. else // AF_INET6
  1937. {
  1938. address_length = sizeof(sockaddr_in6_type);
  1939. address.v6.sin6_family = BOOST_ASIO_OS_DEF(AF_INET6);
  1940. address.v6.sin6_port = 0;
  1941. address.v6.sin6_flowinfo = 0;
  1942. address.v6.sin6_scope_id = scope_id;
  1943. memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type));
  1944. }
  1945.  
  1946. DWORD string_length = static_cast<DWORD>(length);
  1947. #if defined(BOOST_NO_ANSI_APIS)
  1948. LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR));
  1949. int result = error_wrapper(::WSAAddressToStringW(&address.base,
  1950. address_length, 0, string_buffer, &string_length), ec);
  1951. ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0);
  1952. #else
  1953. int result = error_wrapper(::WSAAddressToStringA(
  1954. &address.base, address_length, 0, dest, &string_length), ec);
  1955. #endif
  1956.  
  1957. // Windows may set error code on success.
  1958. if (result != socket_error_retval)
  1959. ec = boost::system::error_code();
  1960.  
  1961. // Windows may not set an error code on failure.
  1962. else if (result == socket_error_retval && !ec)
  1963. ec = boost::asio::error::invalid_argument;
  1964.  
  1965. return result == socket_error_retval ? 0 : dest;
  1966. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1967. const char* result = error_wrapper(::inet_ntop(
  1968. af, src, dest, static_cast<int>(length)), ec);
  1969. if (result == 0 && !ec)
  1970. ec = boost::asio::error::invalid_argument;
  1971. if (result != 0 && af == BOOST_ASIO_OS_DEF(AF_INET6) && scope_id != 0)
  1972. {
  1973. using namespace std; // For strcat and sprintf.
  1974. char if_name[IF_NAMESIZE + 1] = "%";
  1975. const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src);
  1976. bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe)
  1977. && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80));
  1978. if (!is_link_local
  1979. || if_indextoname(static_cast<unsigned>(scope_id), if_name + 1) == 0)
  1980. sprintf(if_name + 1, "%lu", scope_id);
  1981. strcat(dest, if_name);
  1982. }
  1983. return result;
  1984. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  1985. }
  1986.  
  1987. int inet_pton(int af, const char* src, void* dest,
  1988. unsigned long* scope_id, boost::system::error_code& ec)
  1989. {
  1990. clear_last_error();
  1991. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  1992. using namespace std; // For sscanf.
  1993. unsigned char* bytes = static_cast<unsigned char*>(dest);
  1994. if (af == BOOST_ASIO_OS_DEF(AF_INET))
  1995. {
  1996. unsigned int b0, b1, b2, b3;
  1997. if (sscanf_s(src, "%u.%u.%u.%u", &b0, &b1, &b2, &b3) != 4)
  1998. {
  1999. ec = boost::asio::error::invalid_argument;
  2000. return -1;
  2001. }
  2002. if (b0 > 255 || b1 > 255 || b2 > 255 || b3 > 255)
  2003. {
  2004. ec = boost::asio::error::invalid_argument;
  2005. return -1;
  2006. }
  2007. bytes[0] = static_cast<unsigned char>(b0);
  2008. bytes[1] = static_cast<unsigned char>(b1);
  2009. bytes[2] = static_cast<unsigned char>(b2);
  2010. bytes[3] = static_cast<unsigned char>(b3);
  2011. ec = boost::system::error_code();
  2012. return 1;
  2013. }
  2014. else if (af == BOOST_ASIO_OS_DEF(AF_INET6))
  2015. {
  2016. unsigned char* bytes = static_cast<unsigned char*>(dest);
  2017. std::memset(bytes, 0, 16);
  2018. unsigned char back_bytes[16] = { 0 };
  2019. int num_front_bytes = 0, num_back_bytes = 0;
  2020. const char* p = src;
  2021.  
  2022. enum { fword, fcolon, bword, scope, done } state = fword;
  2023. unsigned long current_word = 0;
  2024. while (state != done)
  2025. {
  2026. if (current_word > 0xFFFF)
  2027. {
  2028. ec = boost::asio::error::invalid_argument;
  2029. return -1;
  2030. }
  2031.  
  2032. switch (state)
  2033. {
  2034. case fword:
  2035. if (*p >= '0' && *p <= '9')
  2036. current_word = current_word * 16 + *p++ - '0';
  2037. else if (*p >= 'a' && *p <= 'f')
  2038. current_word = current_word * 16 + *p++ - 'a' + 10;
  2039. else if (*p >= 'A' && *p <= 'F')
  2040. current_word = current_word * 16 + *p++ - 'A' + 10;
  2041. else
  2042. {
  2043. if (num_front_bytes == 16)
  2044. {
  2045. ec = boost::asio::error::invalid_argument;
  2046. return -1;
  2047. }
  2048.  
  2049. bytes[num_front_bytes++] = (current_word >> 8) & 0xFF;
  2050. bytes[num_front_bytes++] = current_word & 0xFF;
  2051. current_word = 0;
  2052.  
  2053. if (*p == ':')
  2054. state = fcolon, ++p;
  2055. else if (*p == '%')
  2056. state = scope, ++p;
  2057. else if (*p == 0)
  2058. state = done;
  2059. else
  2060. {
  2061. ec = boost::asio::error::invalid_argument;
  2062. return -1;
  2063. }
  2064. }
  2065. break;
  2066.  
  2067. case fcolon:
  2068. if (*p == ':')
  2069. state = bword, ++p;
  2070. else
  2071. state = fword;
  2072. break;
  2073.  
  2074. case bword:
  2075. if (*p >= '0' && *p <= '9')
  2076. current_word = current_word * 16 + *p++ - '0';
  2077. else if (*p >= 'a' && *p <= 'f')
  2078. current_word = current_word * 16 + *p++ - 'a' + 10;
  2079. else if (*p >= 'A' && *p <= 'F')
  2080. current_word = current_word * 16 + *p++ - 'A' + 10;
  2081. else
  2082. {
  2083. if (num_front_bytes + num_back_bytes == 16)
  2084. {
  2085. ec = boost::asio::error::invalid_argument;
  2086. return -1;
  2087. }
  2088.  
  2089. back_bytes[num_back_bytes++] = (current_word >> 8) & 0xFF;
  2090. back_bytes[num_back_bytes++] = current_word & 0xFF;
  2091. current_word = 0;
  2092.  
  2093. if (*p == ':')
  2094. state = bword, ++p;
  2095. else if (*p == '%')
  2096. state = scope, ++p;
  2097. else if (*p == 0)
  2098. state = done;
  2099. else
  2100. {
  2101. ec = boost::asio::error::invalid_argument;
  2102. return -1;
  2103. }
  2104. }
  2105. break;
  2106.  
  2107. case scope:
  2108. if (*p >= '0' && *p <= '9')
  2109. current_word = current_word * 10 + *p++ - '0';
  2110. else if (*p == 0)
  2111. *scope_id = current_word, state = done;
  2112. else
  2113. {
  2114. ec = boost::asio::error::invalid_argument;
  2115. return -1;
  2116. }
  2117. break;
  2118.  
  2119. default:
  2120. break;
  2121. }
  2122. }
  2123.  
  2124. for (int i = 0; i < num_back_bytes; ++i)
  2125. bytes[16 - num_back_bytes + i] = back_bytes[i];
  2126.  
  2127. ec = boost::system::error_code();
  2128. return 1;
  2129. }
  2130. else
  2131. {
  2132. ec = boost::asio::error::address_family_not_supported;
  2133. return -1;
  2134. }
  2135. #elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  2136. using namespace std; // For memcpy and strcmp.
  2137.  
  2138. if (af != BOOST_ASIO_OS_DEF(AF_INET) && af != BOOST_ASIO_OS_DEF(AF_INET6))
  2139. {
  2140. ec = boost::asio::error::address_family_not_supported;
  2141. return -1;
  2142. }
  2143.  
  2144. union
  2145. {
  2146. socket_addr_type base;
  2147. sockaddr_storage_type storage;
  2148. sockaddr_in4_type v4;
  2149. sockaddr_in6_type v6;
  2150. } address;
  2151. int address_length = sizeof(sockaddr_storage_type);
  2152. #if defined(BOOST_NO_ANSI_APIS)
  2153. int num_wide_chars = strlen(src) + 1;
  2154. LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR));
  2155. ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars);
  2156. int result = error_wrapper(::WSAStringToAddressW(
  2157. wide_buffer, af, 0, &address.base, &address_length), ec);
  2158. #else
  2159. int result = error_wrapper(::WSAStringToAddressA(
  2160. const_cast<char*>(src), af, 0, &address.base, &address_length), ec);
  2161. #endif
  2162.  
  2163. if (af == BOOST_ASIO_OS_DEF(AF_INET))
  2164. {
  2165. if (result != socket_error_retval)
  2166. {
  2167. memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type));
  2168. ec = boost::system::error_code();
  2169. }
  2170. else if (strcmp(src, "255.255.255.255") == 0)
  2171. {
  2172. static_cast<in4_addr_type*>(dest)->s_addr = INADDR_NONE;
  2173. ec = boost::system::error_code();
  2174. }
  2175. }
  2176. else // AF_INET6
  2177. {
  2178. if (result != socket_error_retval)
  2179. {
  2180. memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type));
  2181. if (scope_id)
  2182. *scope_id = address.v6.sin6_scope_id;
  2183. ec = boost::system::error_code();
  2184. }
  2185. }
  2186.  
  2187. // Windows may not set an error code on failure.
  2188. if (result == socket_error_retval && !ec)
  2189. ec = boost::asio::error::invalid_argument;
  2190.  
  2191. if (result != socket_error_retval)
  2192. ec = boost::system::error_code();
  2193.  
  2194. return result == socket_error_retval ? -1 : 1;
  2195. #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  2196. int result = error_wrapper(::inet_pton(af, src, dest), ec);
  2197. if (result <= 0 && !ec)
  2198. ec = boost::asio::error::invalid_argument;
  2199. if (result > 0 && af == BOOST_ASIO_OS_DEF(AF_INET6) && scope_id)
  2200. {
  2201. using namespace std; // For strchr and atoi.
  2202. *scope_id = 0;
  2203. if (const char* if_name = strchr(src, '%'))
  2204. {
  2205. in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest);
  2206. bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe)
  2207. && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80));
  2208. if (is_link_local)
  2209. *scope_id = if_nametoindex(if_name + 1);
  2210. if (*scope_id == 0)
  2211. *scope_id = atoi(if_name + 1);
  2212. }
  2213. }
  2214. return result;
  2215. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  2216. }
  2217.  
  2218. int gethostname(char* name, int namelen, boost::system::error_code& ec)
  2219. {
  2220. clear_last_error();
  2221. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  2222. try
  2223. {
  2224. using namespace Windows::Foundation::Collections;
  2225. using namespace Windows::Networking;
  2226. using namespace Windows::Networking::Connectivity;
  2227. IVectorView<HostName^>^ hostnames = NetworkInformation::GetHostNames();
  2228. for (unsigned i = 0; i < hostnames->Size; ++i)
  2229. {
  2230. HostName^ hostname = hostnames->GetAt(i);
  2231. if (hostname->Type == HostNameType::DomainName)
  2232. {
  2233. std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
  2234. std::string raw_name = converter.to_bytes(hostname->RawName->Data());
  2235. if (namelen > 0 && raw_name.size() < static_cast<std::size_t>(namelen))
  2236. {
  2237. strcpy_s(name, namelen, raw_name.c_str());
  2238. return 0;
  2239. }
  2240. }
  2241. }
  2242. return -1;
  2243. }
  2244. catch (Platform::Exception^ e)
  2245. {
  2246. ec = boost::system::error_code(e->HResult,
  2247. boost::system::system_category());
  2248. return -1;
  2249. }
  2250. #else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  2251. int result = error_wrapper(::gethostname(name, namelen), ec);
  2252. # if defined(BOOST_ASIO_WINDOWS)
  2253. if (result == 0)
  2254. ec = boost::system::error_code();
  2255. # endif // defined(BOOST_ASIO_WINDOWS)
  2256. return result;
  2257. #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  2258. }
  2259.  
  2260. #if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
  2261.  
  2262. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) \
  2263. || defined(__MACH__) && defined(__APPLE__)
  2264.  
  2265. // The following functions are only needed for emulation of getaddrinfo and
  2266. // getnameinfo.
  2267.  
  2268. inline boost::system::error_code translate_netdb_error(int error)
  2269. {
  2270. switch (error)
  2271. {
  2272. case 0:
  2273. return boost::system::error_code();
  2274. case HOST_NOT_FOUND:
  2275. return boost::asio::error::host_not_found;
  2276. case TRY_AGAIN:
  2277. return boost::asio::error::host_not_found_try_again;
  2278. case NO_RECOVERY:
  2279. return boost::asio::error::no_recovery;
  2280. case NO_DATA:
  2281. return boost::asio::error::no_data;
  2282. default:
  2283. BOOST_ASIO_ASSERT(false);
  2284. return boost::asio::error::invalid_argument;
  2285. }
  2286. }
  2287.  
  2288. inline hostent* gethostbyaddr(const char* addr, int length, int af,
  2289. hostent* result, char* buffer, int buflength, boost::system::error_code& ec)
  2290. {
  2291. clear_last_error();
  2292. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  2293. (void)(buffer);
  2294. (void)(buflength);
  2295. hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);
  2296. if (!retval)
  2297. return 0;
  2298. ec = boost::system::error_code();
  2299. *result = *retval;
  2300. return retval;
  2301. #elif defined(__sun) || defined(__QNX__)
  2302. int error = 0;
  2303. hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result,
  2304. buffer, buflength, &error), ec);
  2305. if (error)
  2306. ec = translate_netdb_error(error);
  2307. return retval;
  2308. #elif defined(__MACH__) && defined(__APPLE__)
  2309. (void)(buffer);
  2310. (void)(buflength);
  2311. int error = 0;
  2312. hostent* retval = error_wrapper(::getipnodebyaddr(
  2313. addr, length, af, &error), ec);
  2314. if (error)
  2315. ec = translate_netdb_error(error);
  2316. if (!retval)
  2317. return 0;
  2318. *result = *retval;
  2319. return retval;
  2320. #else
  2321. hostent* retval = 0;
  2322. int error = 0;
  2323. error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer,
  2324. buflength, &retval, &error), ec);
  2325. if (error)
  2326. ec = translate_netdb_error(error);
  2327. return retval;
  2328. #endif
  2329. }
  2330.  
  2331. inline hostent* gethostbyname(const char* name, int af, struct hostent* result,
  2332. char* buffer, int buflength, int ai_flags, boost::system::error_code& ec)
  2333. {
  2334. clear_last_error();
  2335. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  2336. (void)(buffer);
  2337. (void)(buflength);
  2338. (void)(ai_flags);
  2339. if (af != BOOST_ASIO_OS_DEF(AF_INET))
  2340. {
  2341. ec = boost::asio::error::address_family_not_supported;
  2342. return 0;
  2343. }
  2344. hostent* retval = error_wrapper(::gethostbyname(name), ec);
  2345. if (!retval)
  2346. return 0;
  2347. ec = boost::system::error_code();
  2348. *result = *retval;
  2349. return result;
  2350. #elif defined(__sun) || defined(__QNX__)
  2351. (void)(ai_flags);
  2352. if (af != BOOST_ASIO_OS_DEF(AF_INET))
  2353. {
  2354. ec = boost::asio::error::address_family_not_supported;
  2355. return 0;
  2356. }
  2357. int error = 0;
  2358. hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer,
  2359. buflength, &error), ec);
  2360. if (error)
  2361. ec = translate_netdb_error(error);
  2362. return retval;
  2363. #elif defined(__MACH__) && defined(__APPLE__)
  2364. (void)(buffer);
  2365. (void)(buflength);
  2366. int error = 0;
  2367. hostent* retval = error_wrapper(::getipnodebyname(
  2368. name, af, ai_flags, &error), ec);
  2369. if (error)
  2370. ec = translate_netdb_error(error);
  2371. if (!retval)
  2372. return 0;
  2373. *result = *retval;
  2374. return retval;
  2375. #else
  2376. (void)(ai_flags);
  2377. if (af != BOOST_ASIO_OS_DEF(AF_INET))
  2378. {
  2379. ec = boost::asio::error::address_family_not_supported;
  2380. return 0;
  2381. }
  2382. hostent* retval = 0;
  2383. int error = 0;
  2384. error_wrapper(::gethostbyname_r(name, result,
  2385. buffer, buflength, &retval, &error), ec);
  2386. if (error)
  2387. ec = translate_netdb_error(error);
  2388. return retval;
  2389. #endif
  2390. }
  2391.  
  2392. inline void freehostent(hostent* h)
  2393. {
  2394. #if defined(__MACH__) && defined(__APPLE__)
  2395. if (h)
  2396. ::freehostent(h);
  2397. #else
  2398. (void)(h);
  2399. #endif
  2400. }
  2401.  
  2402. // Emulation of getaddrinfo based on implementation in:
  2403. // Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998.
  2404.  
  2405. struct gai_search
  2406. {
  2407. const char* host;
  2408. int family;
  2409. };
  2410.  
  2411. inline int gai_nsearch(const char* host,
  2412. const addrinfo_type* hints, gai_search (&search)[2])
  2413. {
  2414. int search_count = 0;
  2415. if (host == 0 || host[0] == '\0')
  2416. {
  2417. if (hints->ai_flags & AI_PASSIVE)
  2418. {
  2419. // No host and AI_PASSIVE implies wildcard bind.
  2420. switch (hints->ai_family)
  2421. {
  2422. case BOOST_ASIO_OS_DEF(AF_INET):
  2423. search[search_count].host = "0.0.0.0";
  2424. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
  2425. ++search_count;
  2426. break;
  2427. case BOOST_ASIO_OS_DEF(AF_INET6):
  2428. search[search_count].host = "0::0";
  2429. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
  2430. ++search_count;
  2431. break;
  2432. case BOOST_ASIO_OS_DEF(AF_UNSPEC):
  2433. search[search_count].host = "0::0";
  2434. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
  2435. ++search_count;
  2436. search[search_count].host = "0.0.0.0";
  2437. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
  2438. ++search_count;
  2439. break;
  2440. default:
  2441. break;
  2442. }
  2443. }
  2444. else
  2445. {
  2446. // No host and not AI_PASSIVE means connect to local host.
  2447. switch (hints->ai_family)
  2448. {
  2449. case BOOST_ASIO_OS_DEF(AF_INET):
  2450. search[search_count].host = "localhost";
  2451. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
  2452. ++search_count;
  2453. break;
  2454. case BOOST_ASIO_OS_DEF(AF_INET6):
  2455. search[search_count].host = "localhost";
  2456. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
  2457. ++search_count;
  2458. break;
  2459. case BOOST_ASIO_OS_DEF(AF_UNSPEC):
  2460. search[search_count].host = "localhost";
  2461. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
  2462. ++search_count;
  2463. search[search_count].host = "localhost";
  2464. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
  2465. ++search_count;
  2466. break;
  2467. default:
  2468. break;
  2469. }
  2470. }
  2471. }
  2472. else
  2473. {
  2474. // Host is specified.
  2475. switch (hints->ai_family)
  2476. {
  2477. case BOOST_ASIO_OS_DEF(AF_INET):
  2478. search[search_count].host = host;
  2479. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
  2480. ++search_count;
  2481. break;
  2482. case BOOST_ASIO_OS_DEF(AF_INET6):
  2483. search[search_count].host = host;
  2484. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
  2485. ++search_count;
  2486. break;
  2487. case BOOST_ASIO_OS_DEF(AF_UNSPEC):
  2488. search[search_count].host = host;
  2489. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
  2490. ++search_count;
  2491. search[search_count].host = host;
  2492. search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
  2493. ++search_count;
  2494. break;
  2495. default:
  2496. break;
  2497. }
  2498. }
  2499. return search_count;
  2500. }
  2501.  
  2502. template <typename T>
  2503. inline T* gai_alloc(std::size_t size = sizeof(T))
  2504. {
  2505. using namespace std;
  2506. T* p = static_cast<T*>(::operator new(size, std::nothrow));
  2507. if (p)
  2508. memset(p, 0, size);
  2509. return p;
  2510. }
  2511.  
  2512. inline void gai_free(void* p)
  2513. {
  2514. ::operator delete(p);
  2515. }
  2516.  
  2517. inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
  2518. {
  2519. using namespace std;
  2520. #if defined(BOOST_ASIO_HAS_SECURE_RTL)
  2521. strcpy_s(target, max_size, source);
  2522. #else // defined(BOOST_ASIO_HAS_SECURE_RTL)
  2523. *target = 0;
  2524. strncat(target, source, max_size);
  2525. #endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
  2526. }
  2527.  
  2528. enum { gai_clone_flag = 1 << 30 };
  2529.  
  2530. inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
  2531. const void* addr, int family)
  2532. {
  2533. using namespace std;
  2534.  
  2535. addrinfo_type* ai = gai_alloc<addrinfo_type>();
  2536. if (ai == 0)
  2537. return EAI_MEMORY;
  2538.  
  2539. ai->ai_next = 0;
  2540. **next = ai;
  2541. *next = &ai->ai_next;
  2542.  
  2543. ai->ai_canonname = 0;
  2544. ai->ai_socktype = hints->ai_socktype;
  2545. if (ai->ai_socktype == 0)
  2546. ai->ai_flags |= gai_clone_flag;
  2547. ai->ai_protocol = hints->ai_protocol;
  2548. ai->ai_family = family;
  2549.  
  2550. switch (ai->ai_family)
  2551. {
  2552. case BOOST_ASIO_OS_DEF(AF_INET):
  2553. {
  2554. sockaddr_in4_type* sinptr = gai_alloc<sockaddr_in4_type>();
  2555. if (sinptr == 0)
  2556. return EAI_MEMORY;
  2557. sinptr->sin_family = BOOST_ASIO_OS_DEF(AF_INET);
  2558. memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type));
  2559. ai->ai_addr = reinterpret_cast<sockaddr*>(sinptr);
  2560. ai->ai_addrlen = sizeof(sockaddr_in4_type);
  2561. break;
  2562. }
  2563. case BOOST_ASIO_OS_DEF(AF_INET6):
  2564. {
  2565. sockaddr_in6_type* sin6ptr = gai_alloc<sockaddr_in6_type>();
  2566. if (sin6ptr == 0)
  2567. return EAI_MEMORY;
  2568. sin6ptr->sin6_family = BOOST_ASIO_OS_DEF(AF_INET6);
  2569. memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type));
  2570. ai->ai_addr = reinterpret_cast<sockaddr*>(sin6ptr);
  2571. ai->ai_addrlen = sizeof(sockaddr_in6_type);
  2572. break;
  2573. }
  2574. default:
  2575. break;
  2576. }
  2577.  
  2578. return 0;
  2579. }
  2580.  
  2581. inline addrinfo_type* gai_clone(addrinfo_type* ai)
  2582. {
  2583. using namespace std;
  2584.  
  2585. addrinfo_type* new_ai = gai_alloc<addrinfo_type>();
  2586. if (new_ai == 0)
  2587. return new_ai;
  2588.  
  2589. new_ai->ai_next = ai->ai_next;
  2590. ai->ai_next = new_ai;
  2591.  
  2592. new_ai->ai_flags = 0;
  2593. new_ai->ai_family = ai->ai_family;
  2594. new_ai->ai_socktype = ai->ai_socktype;
  2595. new_ai->ai_protocol = ai->ai_protocol;
  2596. new_ai->ai_canonname = 0;
  2597. new_ai->ai_addrlen = ai->ai_addrlen;
  2598. new_ai->ai_addr = gai_alloc<sockaddr>(ai->ai_addrlen);
  2599. memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen);
  2600.  
  2601. return new_ai;
  2602. }
  2603.  
  2604. inline int gai_port(addrinfo_type* aihead, int port, int socktype)
  2605. {
  2606. int num_found = 0;
  2607.  
  2608. for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next)
  2609. {
  2610. if (ai->ai_flags & gai_clone_flag)
  2611. {
  2612. if (ai->ai_socktype != 0)
  2613. {
  2614. ai = gai_clone(ai);
  2615. if (ai == 0)
  2616. return -1;
  2617. // ai now points to newly cloned entry.
  2618. }
  2619. }
  2620. else if (ai->ai_socktype != socktype)
  2621. {
  2622. // Ignore if mismatch on socket type.
  2623. continue;
  2624. }
  2625.  
  2626. ai->ai_socktype = socktype;
  2627.  
  2628. switch (ai->ai_family)
  2629. {
  2630. case BOOST_ASIO_OS_DEF(AF_INET):
  2631. {
  2632. sockaddr_in4_type* sinptr =
  2633. reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr);
  2634. sinptr->sin_port = port;
  2635. ++num_found;
  2636. break;
  2637. }
  2638. case BOOST_ASIO_OS_DEF(AF_INET6):
  2639. {
  2640. sockaddr_in6_type* sin6ptr =
  2641. reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr);
  2642. sin6ptr->sin6_port = port;
  2643. ++num_found;
  2644. break;
  2645. }
  2646. default:
  2647. break;
  2648. }
  2649. }
  2650.  
  2651. return num_found;
  2652. }
  2653.  
  2654. inline int gai_serv(addrinfo_type* aihead,
  2655. const addrinfo_type* hints, const char* serv)
  2656. {
  2657. using namespace std;
  2658.  
  2659. int num_found = 0;
  2660.  
  2661. if (
  2662. #if defined(AI_NUMERICSERV)
  2663. (hints->ai_flags & AI_NUMERICSERV) ||
  2664. #endif
  2665. isdigit(static_cast<unsigned char>(serv[0])))
  2666. {
  2667. int port = htons(atoi(serv));
  2668. if (hints->ai_socktype)
  2669. {
  2670. // Caller specifies socket type.
  2671. int rc = gai_port(aihead, port, hints->ai_socktype);
  2672. if (rc < 0)
  2673. return EAI_MEMORY;
  2674. num_found += rc;
  2675. }
  2676. else
  2677. {
  2678. // Caller does not specify socket type.
  2679. int rc = gai_port(aihead, port, SOCK_STREAM);
  2680. if (rc < 0)
  2681. return EAI_MEMORY;
  2682. num_found += rc;
  2683. rc = gai_port(aihead, port, SOCK_DGRAM);
  2684. if (rc < 0)
  2685. return EAI_MEMORY;
  2686. num_found += rc;
  2687. }
  2688. }
  2689. else
  2690. {
  2691. // Try service name with TCP first, then UDP.
  2692. if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM)
  2693. {
  2694. servent* sptr = getservbyname(serv, "tcp");
  2695. if (sptr != 0)
  2696. {
  2697. int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM);
  2698. if (rc < 0)
  2699. return EAI_MEMORY;
  2700. num_found += rc;
  2701. }
  2702. }
  2703. if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM)
  2704. {
  2705. servent* sptr = getservbyname(serv, "udp");
  2706. if (sptr != 0)
  2707. {
  2708. int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM);
  2709. if (rc < 0)
  2710. return EAI_MEMORY;
  2711. num_found += rc;
  2712. }
  2713. }
  2714. }
  2715.  
  2716. if (num_found == 0)
  2717. {
  2718. if (hints->ai_socktype == 0)
  2719. {
  2720. // All calls to getservbyname() failed.
  2721. return EAI_NONAME;
  2722. }
  2723. else
  2724. {
  2725. // Service not supported for socket type.
  2726. return EAI_SERVICE;
  2727. }
  2728. }
  2729.  
  2730. return 0;
  2731. }
  2732.  
  2733. inline int gai_echeck(const char* host, const char* service,
  2734. int flags, int family, int socktype, int protocol)
  2735. {
  2736. (void)(flags);
  2737. (void)(protocol);
  2738.  
  2739. // Host or service must be specified.
  2740. if (host == 0 || host[0] == '\0')
  2741. if (service == 0 || service[0] == '\0')
  2742. return EAI_NONAME;
  2743.  
  2744. // Check combination of family and socket type.
  2745. switch (family)
  2746. {
  2747. case BOOST_ASIO_OS_DEF(AF_UNSPEC):
  2748. break;
  2749. case BOOST_ASIO_OS_DEF(AF_INET):
  2750. case BOOST_ASIO_OS_DEF(AF_INET6):
  2751. if (service != 0 && service[0] != '\0')
  2752. if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM)
  2753. return EAI_SOCKTYPE;
  2754. break;
  2755. default:
  2756. return EAI_FAMILY;
  2757. }
  2758.  
  2759. return 0;
  2760. }
  2761.  
  2762. inline void freeaddrinfo_emulation(addrinfo_type* aihead)
  2763. {
  2764. addrinfo_type* ai = aihead;
  2765. while (ai)
  2766. {
  2767. gai_free(ai->ai_addr);
  2768. gai_free(ai->ai_canonname);
  2769. addrinfo_type* ainext = ai->ai_next;
  2770. gai_free(ai);
  2771. ai = ainext;
  2772. }
  2773. }
  2774.  
  2775. inline int getaddrinfo_emulation(const char* host, const char* service,
  2776. const addrinfo_type* hintsp, addrinfo_type** result)
  2777. {
  2778. // Set up linked list of addrinfo structures.
  2779. addrinfo_type* aihead = 0;
  2780. addrinfo_type** ainext = &aihead;
  2781. char* canon = 0;
  2782.  
  2783. // Supply default hints if not specified by caller.
  2784. addrinfo_type hints = addrinfo_type();
  2785. hints.ai_family = BOOST_ASIO_OS_DEF(AF_UNSPEC);
  2786. if (hintsp)
  2787. hints = *hintsp;
  2788.  
  2789. // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED
  2790. // and AI_ALL flags.
  2791. #if defined(AI_V4MAPPED)
  2792. if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6))
  2793. hints.ai_flags &= ~AI_V4MAPPED;
  2794. #endif
  2795. #if defined(AI_ALL)
  2796. if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6))
  2797. hints.ai_flags &= ~AI_ALL;
  2798. #endif
  2799.  
  2800. // Basic error checking.
  2801. int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family,
  2802. hints.ai_socktype, hints.ai_protocol);
  2803. if (rc != 0)
  2804. {
  2805. freeaddrinfo_emulation(aihead);
  2806. return rc;
  2807. }
  2808.  
  2809. gai_search search[2];
  2810. int search_count = gai_nsearch(host, &hints, search);
  2811. for (gai_search* sptr = search; sptr < search + search_count; ++sptr)
  2812. {
  2813. // Check for IPv4 dotted decimal string.
  2814. in4_addr_type inaddr;
  2815. boost::system::error_code ec;
  2816. if (socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET),
  2817. sptr->host, &inaddr, 0, ec) == 1)
  2818. {
  2819. if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC)
  2820. && hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET))
  2821. {
  2822. freeaddrinfo_emulation(aihead);
  2823. gai_free(canon);
  2824. return EAI_FAMILY;
  2825. }
  2826. if (sptr->family == BOOST_ASIO_OS_DEF(AF_INET))
  2827. {
  2828. rc = gai_aistruct(&ainext, &hints, &inaddr, BOOST_ASIO_OS_DEF(AF_INET));
  2829. if (rc != 0)
  2830. {
  2831. freeaddrinfo_emulation(aihead);
  2832. gai_free(canon);
  2833. return rc;
  2834. }
  2835. }
  2836. continue;
  2837. }
  2838.  
  2839. // Check for IPv6 hex string.
  2840. in6_addr_type in6addr;
  2841. if (socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET6),
  2842. sptr->host, &in6addr, 0, ec) == 1)
  2843. {
  2844. if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC)
  2845. && hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6))
  2846. {
  2847. freeaddrinfo_emulation(aihead);
  2848. gai_free(canon);
  2849. return EAI_FAMILY;
  2850. }
  2851. if (sptr->family == BOOST_ASIO_OS_DEF(AF_INET6))
  2852. {
  2853. rc = gai_aistruct(&ainext, &hints, &in6addr,
  2854. BOOST_ASIO_OS_DEF(AF_INET6));
  2855. if (rc != 0)
  2856. {
  2857. freeaddrinfo_emulation(aihead);
  2858. gai_free(canon);
  2859. return rc;
  2860. }
  2861. }
  2862. continue;
  2863. }
  2864.  
  2865. // Look up hostname.
  2866. hostent hent;
  2867. char hbuf[8192] = "";
  2868. hostent* hptr = socket_ops::gethostbyname(sptr->host,
  2869. sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec);
  2870. if (hptr == 0)
  2871. {
  2872. if (search_count == 2)
  2873. {
  2874. // Failure is OK if there are multiple searches.
  2875. continue;
  2876. }
  2877. freeaddrinfo_emulation(aihead);
  2878. gai_free(canon);
  2879. if (ec == boost::asio::error::host_not_found)
  2880. return EAI_NONAME;
  2881. if (ec == boost::asio::error::host_not_found_try_again)
  2882. return EAI_AGAIN;
  2883. if (ec == boost::asio::error::no_recovery)
  2884. return EAI_FAIL;
  2885. if (ec == boost::asio::error::no_data)
  2886. return EAI_NONAME;
  2887. return EAI_NONAME;
  2888. }
  2889.  
  2890. // Check for address family mismatch if one was specified.
  2891. if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC)
  2892. && hints.ai_family != hptr->h_addrtype)
  2893. {
  2894. freeaddrinfo_emulation(aihead);
  2895. gai_free(canon);
  2896. socket_ops::freehostent(hptr);
  2897. return EAI_FAMILY;
  2898. }
  2899.  
  2900. // Save canonical name first time.
  2901. if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
  2902. && (hints.ai_flags & AI_CANONNAME) && canon == 0)
  2903. {
  2904. std::size_t canon_len = strlen(hptr->h_name) + 1;
  2905. canon = gai_alloc<char>(canon_len);
  2906. if (canon == 0)
  2907. {
  2908. freeaddrinfo_emulation(aihead);
  2909. socket_ops::freehostent(hptr);
  2910. return EAI_MEMORY;
  2911. }
  2912. gai_strcpy(canon, hptr->h_name, canon_len);
  2913. }
  2914.  
  2915. // Create an addrinfo structure for each returned address.
  2916. for (char** ap = hptr->h_addr_list; *ap; ++ap)
  2917. {
  2918. rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype);
  2919. if (rc != 0)
  2920. {
  2921. freeaddrinfo_emulation(aihead);
  2922. gai_free(canon);
  2923. socket_ops::freehostent(hptr);
  2924. return EAI_FAMILY;
  2925. }
  2926. }
  2927.  
  2928. socket_ops::freehostent(hptr);
  2929. }
  2930.  
  2931. // Check if we found anything.
  2932. if (aihead == 0)
  2933. {
  2934. gai_free(canon);
  2935. return EAI_NONAME;
  2936. }
  2937.  
  2938. // Return canonical name in first entry.
  2939. if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME))
  2940. {
  2941. if (canon)
  2942. {
  2943. aihead->ai_canonname = canon;
  2944. canon = 0;
  2945. }
  2946. else
  2947. {
  2948. std::size_t canonname_len = strlen(search[0].host) + 1;
  2949. aihead->ai_canonname = gai_alloc<char>(canonname_len);
  2950. if (aihead->ai_canonname == 0)
  2951. {
  2952. freeaddrinfo_emulation(aihead);
  2953. return EAI_MEMORY;
  2954. }
  2955. gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
  2956. }
  2957. }
  2958. gai_free(canon);
  2959.  
  2960. // Process the service name.
  2961. if (service != 0 && service[0] != '\0')
  2962. {
  2963. rc = gai_serv(aihead, &hints, service);
  2964. if (rc != 0)
  2965. {
  2966. freeaddrinfo_emulation(aihead);
  2967. return rc;
  2968. }
  2969. }
  2970.  
  2971. // Return result to caller.
  2972. *result = aihead;
  2973. return 0;
  2974. }
  2975.  
  2976. inline boost::system::error_code getnameinfo_emulation(
  2977. const socket_addr_type* sa, std::size_t salen, char* host,
  2978. std::size_t hostlen, char* serv, std::size_t servlen, int flags,
  2979. boost::system::error_code& ec)
  2980. {
  2981. using namespace std;
  2982.  
  2983. const char* addr;
  2984. size_t addr_len;
  2985. unsigned short port;
  2986. switch (sa->sa_family)
  2987. {
  2988. case BOOST_ASIO_OS_DEF(AF_INET):
  2989. if (salen != sizeof(sockaddr_in4_type))
  2990. {
  2991. return ec = boost::asio::error::invalid_argument;
  2992. }
  2993. addr = reinterpret_cast<const char*>(
  2994. &reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_addr);
  2995. addr_len = sizeof(in4_addr_type);
  2996. port = reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_port;
  2997. break;
  2998. case BOOST_ASIO_OS_DEF(AF_INET6):
  2999. if (salen != sizeof(sockaddr_in6_type))
  3000. {
  3001. return ec = boost::asio::error::invalid_argument;
  3002. }
  3003. addr = reinterpret_cast<const char*>(
  3004. &reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_addr);
  3005. addr_len = sizeof(in6_addr_type);
  3006. port = reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_port;
  3007. break;
  3008. default:
  3009. return ec = boost::asio::error::address_family_not_supported;
  3010. }
  3011.  
  3012. if (host && hostlen > 0)
  3013. {
  3014. if (flags & NI_NUMERICHOST)
  3015. {
  3016. if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0)
  3017. {
  3018. return ec;
  3019. }
  3020. }
  3021. else
  3022. {
  3023. hostent hent;
  3024. char hbuf[8192] = "";
  3025. hostent* hptr = socket_ops::gethostbyaddr(addr,
  3026. static_cast<int>(addr_len), sa->sa_family,
  3027. &hent, hbuf, sizeof(hbuf), ec);
  3028. if (hptr && hptr->h_name && hptr->h_name[0] != '\0')
  3029. {
  3030. if (flags & NI_NOFQDN)
  3031. {
  3032. char* dot = strchr(hptr->h_name, '.');
  3033. if (dot)
  3034. {
  3035. *dot = 0;
  3036. }
  3037. }
  3038. gai_strcpy(host, hptr->h_name, hostlen);
  3039. socket_ops::freehostent(hptr);
  3040. }
  3041. else
  3042. {
  3043. socket_ops::freehostent(hptr);
  3044. if (flags & NI_NAMEREQD)
  3045. {
  3046. return ec = boost::asio::error::host_not_found;
  3047. }
  3048. if (socket_ops::inet_ntop(sa->sa_family,
  3049. addr, host, hostlen, 0, ec) == 0)
  3050. {
  3051. return ec;
  3052. }
  3053. }
  3054. }
  3055. }
  3056.  
  3057. if (serv && servlen > 0)
  3058. {
  3059. if (flags & NI_NUMERICSERV)
  3060. {
  3061. if (servlen < 6)
  3062. {
  3063. return ec = boost::asio::error::no_buffer_space;
  3064. }
  3065. #if defined(BOOST_ASIO_HAS_SECURE_RTL)
  3066. sprintf_s(serv, servlen, "%u", ntohs(port));
  3067. #else // defined(BOOST_ASIO_HAS_SECURE_RTL)
  3068. sprintf(serv, "%u", ntohs(port));
  3069. #endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
  3070. }
  3071. else
  3072. {
  3073. #if defined(BOOST_ASIO_HAS_PTHREADS)
  3074. static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  3075. ::pthread_mutex_lock(&mutex);
  3076. #endif // defined(BOOST_ASIO_HAS_PTHREADS)
  3077. servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
  3078. if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
  3079. {
  3080. gai_strcpy(serv, sptr->s_name, servlen);
  3081. }
  3082. else
  3083. {
  3084. if (servlen < 6)
  3085. {
  3086. return ec = boost::asio::error::no_buffer_space;
  3087. }
  3088. #if defined(BOOST_ASIO_HAS_SECURE_RTL)
  3089. sprintf_s(serv, servlen, "%u", ntohs(port));
  3090. #else // defined(BOOST_ASIO_HAS_SECURE_RTL)
  3091. sprintf(serv, "%u", ntohs(port));
  3092. #endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
  3093. }
  3094. #if defined(BOOST_ASIO_HAS_PTHREADS)
  3095. ::pthread_mutex_unlock(&mutex);
  3096. #endif // defined(BOOST_ASIO_HAS_PTHREADS)
  3097. }
  3098. }
  3099.  
  3100. ec = boost::system::error_code();
  3101. return ec;
  3102. }
  3103.  
  3104. #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  3105. // || defined(__MACH__) && defined(__APPLE__)
  3106.  
  3107. inline boost::system::error_code translate_addrinfo_error(int error)
  3108. {
  3109. switch (error)
  3110. {
  3111. case 0:
  3112. return boost::system::error_code();
  3113. case EAI_AGAIN:
  3114. return boost::asio::error::host_not_found_try_again;
  3115. case EAI_BADFLAGS:
  3116. return boost::asio::error::invalid_argument;
  3117. case EAI_FAIL:
  3118. return boost::asio::error::no_recovery;
  3119. case EAI_FAMILY:
  3120. return boost::asio::error::address_family_not_supported;
  3121. case EAI_MEMORY:
  3122. return boost::asio::error::no_memory;
  3123. case EAI_NONAME:
  3124. #if defined(EAI_ADDRFAMILY)
  3125. case EAI_ADDRFAMILY:
  3126. #endif
  3127. #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
  3128. case EAI_NODATA:
  3129. #endif
  3130. return boost::asio::error::host_not_found;
  3131. case EAI_SERVICE:
  3132. return boost::asio::error::service_not_found;
  3133. case EAI_SOCKTYPE:
  3134. return boost::asio::error::socket_type_not_supported;
  3135. default: // Possibly the non-portable EAI_SYSTEM.
  3136. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  3137. return boost::system::error_code(
  3138. WSAGetLastError(), boost::asio::error::get_system_category());
  3139. #else
  3140. return boost::system::error_code(
  3141. errno, boost::asio::error::get_system_category());
  3142. #endif
  3143. }
  3144. }
  3145.  
  3146. boost::system::error_code getaddrinfo(const char* host,
  3147. const char* service, const addrinfo_type& hints,
  3148. addrinfo_type** result, boost::system::error_code& ec)
  3149. {
  3150. host = (host && *host) ? host : 0;
  3151. service = (service && *service) ? service : 0;
  3152. clear_last_error();
  3153. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  3154. # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
  3155. // Building for Windows XP, Windows Server 2003, or later.
  3156. int error = ::getaddrinfo(host, service, &hints, result);
  3157. return ec = translate_addrinfo_error(error);
  3158. # else
  3159. // Building for Windows 2000 or earlier.
  3160. typedef int (WSAAPI *gai_t)(const char*,
  3161. const char*, const addrinfo_type*, addrinfo_type**);
  3162. if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
  3163. {
  3164. if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo"))
  3165. {
  3166. int error = gai(host, service, &hints, result);
  3167. return ec = translate_addrinfo_error(error);
  3168. }
  3169. }
  3170. int error = getaddrinfo_emulation(host, service, &hints, result);
  3171. return ec = translate_addrinfo_error(error);
  3172. # endif
  3173. #elif defined(__MACH__) && defined(__APPLE__)
  3174. int error = getaddrinfo_emulation(host, service, &hints, result);
  3175. return ec = translate_addrinfo_error(error);
  3176. #else
  3177. int error = ::getaddrinfo(host, service, &hints, result);
  3178. return ec = translate_addrinfo_error(error);
  3179. #endif
  3180. }
  3181.  
  3182. boost::system::error_code background_getaddrinfo(
  3183. const weak_cancel_token_type& cancel_token, const char* host,
  3184. const char* service, const addrinfo_type& hints,
  3185. addrinfo_type** result, boost::system::error_code& ec)
  3186. {
  3187. if (cancel_token.expired())
  3188. ec = boost::asio::error::operation_aborted;
  3189. else
  3190. socket_ops::getaddrinfo(host, service, hints, result, ec);
  3191. return ec;
  3192. }
  3193.  
  3194. void freeaddrinfo(addrinfo_type* ai)
  3195. {
  3196. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  3197. # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
  3198. // Building for Windows XP, Windows Server 2003, or later.
  3199. ::freeaddrinfo(ai);
  3200. # else
  3201. // Building for Windows 2000 or earlier.
  3202. typedef int (WSAAPI *fai_t)(addrinfo_type*);
  3203. if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
  3204. {
  3205. if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo"))
  3206. {
  3207. fai(ai);
  3208. return;
  3209. }
  3210. }
  3211. freeaddrinfo_emulation(ai);
  3212. # endif
  3213. #elif defined(__MACH__) && defined(__APPLE__)
  3214. freeaddrinfo_emulation(ai);
  3215. #else
  3216. ::freeaddrinfo(ai);
  3217. #endif
  3218. }
  3219.  
  3220. boost::system::error_code getnameinfo(const socket_addr_type* addr,
  3221. std::size_t addrlen, char* host, std::size_t hostlen,
  3222. char* serv, std::size_t servlen, int flags, boost::system::error_code& ec)
  3223. {
  3224. #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
  3225. # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
  3226. // Building for Windows XP, Windows Server 2003, or later.
  3227. clear_last_error();
  3228. int error = ::getnameinfo(addr, static_cast<socklen_t>(addrlen),
  3229. host, static_cast<DWORD>(hostlen),
  3230. serv, static_cast<DWORD>(servlen), flags);
  3231. return ec = translate_addrinfo_error(error);
  3232. # else
  3233. // Building for Windows 2000 or earlier.
  3234. typedef int (WSAAPI *gni_t)(const socket_addr_type*,
  3235. int, char*, DWORD, char*, DWORD, int);
  3236. if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
  3237. {
  3238. if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))
  3239. {
  3240. clear_last_error();
  3241. int error = gni(addr, static_cast<int>(addrlen),
  3242. host, static_cast<DWORD>(hostlen),
  3243. serv, static_cast<DWORD>(servlen), flags);
  3244. return ec = translate_addrinfo_error(error);
  3245. }
  3246. }
  3247. clear_last_error();
  3248. return getnameinfo_emulation(addr, addrlen,
  3249. host, hostlen, serv, servlen, flags, ec);
  3250. # endif
  3251. #elif defined(__MACH__) && defined(__APPLE__)
  3252. using namespace std; // For memcpy.
  3253. sockaddr_storage_type tmp_addr;
  3254. memcpy(&tmp_addr, addr, addrlen);
  3255. tmp_addr.ss_len = addrlen;
  3256. addr = reinterpret_cast<socket_addr_type*>(&tmp_addr);
  3257. clear_last_error();
  3258. return getnameinfo_emulation(addr, addrlen,
  3259. host, hostlen, serv, servlen, flags, ec);
  3260. #else
  3261. clear_last_error();
  3262. int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
  3263. return ec = translate_addrinfo_error(error);
  3264. #endif
  3265. }
  3266.  
  3267. boost::system::error_code sync_getnameinfo(
  3268. const socket_addr_type* addr, std::size_t addrlen,
  3269. char* host, std::size_t hostlen, char* serv,
  3270. std::size_t servlen, int sock_type, boost::system::error_code& ec)
  3271. {
  3272. // First try resolving with the service name. If that fails try resolving
  3273. // but allow the service to be returned as a number.
  3274. int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
  3275. socket_ops::getnameinfo(addr, addrlen, host,
  3276. hostlen, serv, servlen, flags, ec);
  3277. if (ec)
  3278. {
  3279. socket_ops::getnameinfo(addr, addrlen, host, hostlen,
  3280. serv, servlen, flags | NI_NUMERICSERV, ec);
  3281. }
  3282.  
  3283. return ec;
  3284. }
  3285.  
  3286. boost::system::error_code background_getnameinfo(
  3287. const weak_cancel_token_type& cancel_token,
  3288. const socket_addr_type* addr, std::size_t addrlen,
  3289. char* host, std::size_t hostlen, char* serv,
  3290. std::size_t servlen, int sock_type, boost::system::error_code& ec)
  3291. {
  3292. if (cancel_token.expired())
  3293. {
  3294. ec = boost::asio::error::operation_aborted;
  3295. }
  3296. else
  3297. {
  3298. // First try resolving with the service name. If that fails try resolving
  3299. // but allow the service to be returned as a number.
  3300. int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
  3301. socket_ops::getnameinfo(addr, addrlen, host,
  3302. hostlen, serv, servlen, flags, ec);
  3303. if (ec)
  3304. {
  3305. socket_ops::getnameinfo(addr, addrlen, host, hostlen,
  3306. serv, servlen, flags | NI_NUMERICSERV, ec);
  3307. }
  3308. }
  3309.  
  3310. return ec;
  3311. }
  3312.  
  3313. #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3314.  
  3315. u_long_type network_to_host_long(u_long_type value)
  3316. {
  3317. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3318. unsigned char* value_p = reinterpret_cast<unsigned char*>(&value);
  3319. u_long_type result = (static_cast<u_long_type>(value_p[0]) << 24)
  3320. | (static_cast<u_long_type>(value_p[1]) << 16)
  3321. | (static_cast<u_long_type>(value_p[2]) << 8)
  3322. | static_cast<u_long_type>(value_p[3]);
  3323. return result;
  3324. #else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3325. return ntohl(value);
  3326. #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3327. }
  3328.  
  3329. u_long_type host_to_network_long(u_long_type value)
  3330. {
  3331. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3332. u_long_type result;
  3333. unsigned char* result_p = reinterpret_cast<unsigned char*>(&result);
  3334. result_p[0] = static_cast<unsigned char>((value >> 24) & 0xFF);
  3335. result_p[1] = static_cast<unsigned char>((value >> 16) & 0xFF);
  3336. result_p[2] = static_cast<unsigned char>((value >> 8) & 0xFF);
  3337. result_p[3] = static_cast<unsigned char>(value & 0xFF);
  3338. return result;
  3339. #else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3340. return htonl(value);
  3341. #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3342. }
  3343.  
  3344. u_short_type network_to_host_short(u_short_type value)
  3345. {
  3346. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3347. unsigned char* value_p = reinterpret_cast<unsigned char*>(&value);
  3348. u_short_type result = (static_cast<u_long_type>(value_p[0]) << 8)
  3349. | static_cast<u_long_type>(value_p[1]);
  3350. return result;
  3351. #else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3352. return ntohs(value);
  3353. #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3354. }
  3355.  
  3356. u_short_type host_to_network_short(u_short_type value)
  3357. {
  3358. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3359. u_long_type result;
  3360. unsigned char* result_p = reinterpret_cast<unsigned char*>(&result);
  3361. result_p[0] = static_cast<unsigned char>((value >> 8) & 0xFF);
  3362. result_p[1] = static_cast<unsigned char>(value & 0xFF);
  3363. return result;
  3364. #else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3365. return htons(value);
  3366. #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  3367. }
  3368.  
  3369. } // namespace socket_ops
  3370. } // namespace detail
  3371. } // namespace asio
  3372. } // namespace boost
  3373.  
  3374. #include <boost/asio/detail/pop_options.hpp>
  3375.  
  3376. #endif // BOOST_ASIO_DETAIL_SOCKET_OPS_IPP
Advertisement
Add Comment
Please, Sign In to add comment