Home | History | Annotate | Download | only in impl
      1 //
      2 // detail/impl/socket_ops.ipp
      3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
      4 //
      5 // Copyright (c) 2003-2015 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 ASIO_DETAIL_SOCKET_OPS_IPP
     12 #define ASIO_DETAIL_SOCKET_OPS_IPP
     13 
     14 
     15 #include "asio/detail/config.hpp"
     16 
     17 #include <cctype>
     18 #include <cstdio>
     19 #include <cstdlib>
     20 #include <cstring>
     21 #include <cerrno>
     22 #include <new>
     23 #include "asio/detail/assert.hpp"
     24 #include "asio/detail/socket_ops.hpp"
     25 #include "asio/error.hpp"
     26 
     27 
     28 #if defined(ASIO_WINDOWS) || defined(__CYGWIN__)    || defined(__MACH__) && defined(__APPLE__)
     29 # if defined(ASIO_HAS_PTHREADS)
     30 #  include <pthread.h>
     31 # endif // defined(ASIO_HAS_PTHREADS)
     32 #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
     33        // || defined(__MACH__) && defined(__APPLE__)
     34 
     35 #include "asio/detail/push_options.hpp"
     36 
     37 namespace asio {
     38 namespace detail {
     39 namespace socket_ops {
     40 
     41 
     42 
     43 #if defined(__hpux)
     44 // HP-UX doesn't declare these functions extern "C", so they are declared again
     45 // here to avoid linker errors about undefined symbols.
     46 extern "C" char* if_indextoname(unsigned int, char*);
     47 extern "C" unsigned int if_nametoindex(const char*);
     48 #endif // defined(__hpux)
     49 
     50 
     51 inline void clear_last_error()
     52 {
     53   errno = 0;
     54 }
     55 
     56 
     57 template <typename ReturnType>
     58 inline ReturnType error_wrapper(ReturnType return_value,
     59     asio::error_code& ec)
     60 {
     61   ec = asio::error_code(errno,
     62       asio::error::get_system_category());
     63   return return_value;
     64 }
     65 
     66 template <typename SockLenType>
     67 inline socket_type call_accept(SockLenType msghdr::*,
     68     socket_type s, socket_addr_type* addr, std::size_t* addrlen)
     69 {
     70   SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
     71   socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
     72   if (addrlen)
     73     *addrlen = (std::size_t)tmp_addrlen;
     74   return result;
     75 }
     76 
     77 socket_type accept(socket_type s, socket_addr_type* addr,
     78     std::size_t* addrlen, asio::error_code& ec)
     79 {
     80   if (s == invalid_socket)
     81   {
     82     ec = asio::error::bad_descriptor;
     83     return invalid_socket;
     84   }
     85 
     86   clear_last_error();
     87 
     88   socket_type new_s = error_wrapper(call_accept(
     89         &msghdr::msg_namelen, s, addr, addrlen), ec);
     90   if (new_s == invalid_socket)
     91     return new_s;
     92 
     93 #if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
     94   int optval = 1;
     95   int result = error_wrapper(::setsockopt(new_s,
     96         SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
     97   if (result != 0)
     98   {
     99     ::close(new_s);
    100     return invalid_socket;
    101   }
    102 #endif
    103 
    104   ec = asio::error_code();
    105   return new_s;
    106 }
    107 
    108 socket_type sync_accept(socket_type s, state_type state,
    109     socket_addr_type* addr, std::size_t* addrlen, asio::error_code& ec)
    110 {
    111   // Accept a socket.
    112   for (;;)
    113   {
    114     // Try to complete the operation without blocking.
    115     socket_type new_socket = socket_ops::accept(s, addr, addrlen, ec);
    116 
    117     // Check if operation succeeded.
    118     if (new_socket != invalid_socket)
    119       return new_socket;
    120 
    121     // Operation failed.
    122     if (ec == asio::error::would_block
    123         || ec == asio::error::try_again)
    124     {
    125       if (state & user_set_non_blocking)
    126         return invalid_socket;
    127       // Fall through to retry operation.
    128     }
    129     else if (ec == asio::error::connection_aborted)
    130     {
    131       if (state & enable_connection_aborted)
    132         return invalid_socket;
    133       // Fall through to retry operation.
    134     }
    135 #if defined(EPROTO)
    136     else if (ec.value() == EPROTO)
    137     {
    138       if (state & enable_connection_aborted)
    139         return invalid_socket;
    140       // Fall through to retry operation.
    141     }
    142 #endif // defined(EPROTO)
    143     else
    144       return invalid_socket;
    145 
    146     // Wait for socket to become ready.
    147     if (socket_ops::poll_read(s, 0, ec) < 0)
    148       return invalid_socket;
    149   }
    150 }
    151 
    152 
    153 bool non_blocking_accept(socket_type s,
    154     state_type state, socket_addr_type* addr, std::size_t* addrlen,
    155     asio::error_code& ec, socket_type& new_socket)
    156 {
    157   for (;;)
    158   {
    159     // Accept the waiting connection.
    160     new_socket = socket_ops::accept(s, addr, addrlen, ec);
    161 
    162     // Check if operation succeeded.
    163     if (new_socket != invalid_socket)
    164       return true;
    165 
    166     // Retry operation if interrupted by signal.
    167     if (ec == asio::error::interrupted)
    168       continue;
    169 
    170     // Operation failed.
    171     if (ec == asio::error::would_block
    172         || ec == asio::error::try_again)
    173     {
    174       if (state & user_set_non_blocking)
    175         return true;
    176       // Fall through to retry operation.
    177     }
    178     else if (ec == asio::error::connection_aborted)
    179     {
    180       if (state & enable_connection_aborted)
    181         return true;
    182       // Fall through to retry operation.
    183     }
    184 #if defined(EPROTO)
    185     else if (ec.value() == EPROTO)
    186     {
    187       if (state & enable_connection_aborted)
    188         return true;
    189       // Fall through to retry operation.
    190     }
    191 #endif // defined(EPROTO)
    192     else
    193       return true;
    194 
    195     return false;
    196   }
    197 }
    198 
    199 
    200 template <typename SockLenType>
    201 inline int call_bind(SockLenType msghdr::*,
    202     socket_type s, const socket_addr_type* addr, std::size_t addrlen)
    203 {
    204   return ::bind(s, addr, (SockLenType)addrlen);
    205 }
    206 
    207 int bind(socket_type s, const socket_addr_type* addr,
    208     std::size_t addrlen, asio::error_code& ec)
    209 {
    210   if (s == invalid_socket)
    211   {
    212     ec = asio::error::bad_descriptor;
    213     return socket_error_retval;
    214   }
    215 
    216   clear_last_error();
    217   int result = error_wrapper(call_bind(
    218         &msghdr::msg_namelen, s, addr, addrlen), ec);
    219   if (result == 0)
    220     ec = asio::error_code();
    221   return result;
    222 }
    223 
    224 int close(socket_type s, state_type& state,
    225     bool destruction, asio::error_code& ec)
    226 {
    227   int result = 0;
    228   if (s != invalid_socket)
    229   {
    230     // We don't want the destructor to block, so set the socket to linger in
    231     // the background. If the user doesn't like this behaviour then they need
    232     // to explicitly close the socket.
    233     if (destruction && (state & user_set_linger))
    234     {
    235       ::linger opt;
    236       opt.l_onoff = 0;
    237       opt.l_linger = 0;
    238       asio::error_code ignored_ec;
    239       socket_ops::setsockopt(s, state, SOL_SOCKET,
    240           SO_LINGER, &opt, sizeof(opt), ignored_ec);
    241     }
    242 
    243     clear_last_error();
    244     result = error_wrapper(::close(s), ec);
    245 
    246     if (result != 0
    247         && (ec == asio::error::would_block
    248           || ec == asio::error::try_again))
    249     {
    250       // According to UNIX Network Programming Vol. 1, it is possible for
    251       // close() to fail with EWOULDBLOCK under certain circumstances. What
    252       // isn't clear is the state of the descriptor after this error. The one
    253       // current OS where this behaviour is seen, Windows, says that the socket
    254       // remains open. Therefore we'll put the descriptor back into blocking
    255       // mode and have another attempt at closing it.
    256       ioctl_arg_type arg = 0;
    257       ::ioctl(s, FIONBIO, &arg);
    258       state &= ~non_blocking;
    259 
    260       clear_last_error();
    261       result = error_wrapper(::close(s), ec);
    262     }
    263   }
    264 
    265   if (result == 0)
    266     ec = asio::error_code();
    267   return result;
    268 }
    269 
    270 bool set_user_non_blocking(socket_type s,
    271     state_type& state, bool value, asio::error_code& ec)
    272 {
    273   if (s == invalid_socket)
    274   {
    275     ec = asio::error::bad_descriptor;
    276     return false;
    277   }
    278 
    279   clear_last_error();
    280   ioctl_arg_type arg = (value ? 1 : 0);
    281   int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
    282 
    283   if (result >= 0)
    284   {
    285     ec = asio::error_code();
    286     if (value)
    287       state |= user_set_non_blocking;
    288     else
    289     {
    290       // Clearing the user-set non-blocking mode always overrides any
    291       // internally-set non-blocking flag. Any subsequent asynchronous
    292       // operations will need to re-enable non-blocking I/O.
    293       state &= ~(user_set_non_blocking | internal_non_blocking);
    294     }
    295     return true;
    296   }
    297 
    298   return false;
    299 }
    300 
    301 bool set_internal_non_blocking(socket_type s,
    302     state_type& state, bool value, asio::error_code& ec)
    303 {
    304   if (s == invalid_socket)
    305   {
    306     ec = asio::error::bad_descriptor;
    307     return false;
    308   }
    309 
    310   if (!value && (state & user_set_non_blocking))
    311   {
    312     // It does not make sense to clear the internal non-blocking flag if the
    313     // user still wants non-blocking behaviour. Return an error and let the
    314     // caller figure out whether to update the user-set non-blocking flag.
    315     ec = asio::error::invalid_argument;
    316     return false;
    317   }
    318 
    319   clear_last_error();
    320   ioctl_arg_type arg = (value ? 1 : 0);
    321   int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
    322 
    323   if (result >= 0)
    324   {
    325     ec = asio::error_code();
    326     if (value)
    327       state |= internal_non_blocking;
    328     else
    329       state &= ~internal_non_blocking;
    330     return true;
    331   }
    332 
    333   return false;
    334 }
    335 
    336 int shutdown(socket_type s, int what, asio::error_code& ec)
    337 {
    338   if (s == invalid_socket)
    339   {
    340     ec = asio::error::bad_descriptor;
    341     return socket_error_retval;
    342   }
    343 
    344   clear_last_error();
    345   int result = error_wrapper(::shutdown(s, what), ec);
    346   if (result == 0)
    347     ec = asio::error_code();
    348   return result;
    349 }
    350 
    351 template <typename SockLenType>
    352 inline int call_connect(SockLenType msghdr::*,
    353     socket_type s, const socket_addr_type* addr, std::size_t addrlen)
    354 {
    355   return ::connect(s, addr, (SockLenType)addrlen);
    356 }
    357 
    358 int connect(socket_type s, const socket_addr_type* addr,
    359     std::size_t addrlen, asio::error_code& ec)
    360 {
    361   if (s == invalid_socket)
    362   {
    363     ec = asio::error::bad_descriptor;
    364     return socket_error_retval;
    365   }
    366 
    367   clear_last_error();
    368   int result = error_wrapper(call_connect(
    369         &msghdr::msg_namelen, s, addr, addrlen), ec);
    370   if (result == 0)
    371     ec = asio::error_code();
    372 #if defined(__linux__)
    373   else if (ec == asio::error::try_again)
    374     ec = asio::error::no_buffer_space;
    375 #endif // defined(__linux__)
    376   return result;
    377 }
    378 
    379 void sync_connect(socket_type s, const socket_addr_type* addr,
    380     std::size_t addrlen, asio::error_code& ec)
    381 {
    382   // Perform the connect operation.
    383   socket_ops::connect(s, addr, addrlen, ec);
    384   if (ec != asio::error::in_progress
    385       && ec != asio::error::would_block)
    386   {
    387     // The connect operation finished immediately.
    388     return;
    389   }
    390 
    391   // Wait for socket to become ready.
    392   if (socket_ops::poll_connect(s, ec) < 0)
    393     return;
    394 
    395   // Get the error code from the connect operation.
    396   int connect_error = 0;
    397   size_t connect_error_len = sizeof(connect_error);
    398   if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
    399         &connect_error, &connect_error_len, ec) == socket_error_retval)
    400     return;
    401 
    402   // Return the result of the connect operation.
    403   ec = asio::error_code(connect_error,
    404       asio::error::get_system_category());
    405 }
    406 
    407 
    408 bool non_blocking_connect(socket_type s, asio::error_code& ec)
    409 {
    410   // Check if the connect operation has finished. This is required since we may
    411   // get spurious readiness notifications from the reactor.
    412       // || defined(__CYGWIN__)
    413       // || defined(__SYMBIAN32__)
    414   pollfd fds;
    415   fds.fd = s;
    416   fds.events = POLLOUT;
    417   fds.revents = 0;
    418   int ready = ::poll(&fds, 1, 0);
    419        // || defined(__CYGWIN__)
    420        // || defined(__SYMBIAN32__)
    421   if (ready == 0)
    422   {
    423     // The asynchronous connect operation is still in progress.
    424     return false;
    425   }
    426 
    427   // Get the error code from the connect operation.
    428   int connect_error = 0;
    429   size_t connect_error_len = sizeof(connect_error);
    430   if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
    431         &connect_error, &connect_error_len, ec) == 0)
    432   {
    433     if (connect_error)
    434     {
    435       ec = asio::error_code(connect_error,
    436           asio::error::get_system_category());
    437     }
    438     else
    439       ec = asio::error_code();
    440   }
    441 
    442   return true;
    443 }
    444 
    445 int socketpair(int af, int type, int protocol,
    446     socket_type sv[2], asio::error_code& ec)
    447 {
    448   clear_last_error();
    449   int result = error_wrapper(::socketpair(af, type, protocol, sv), ec);
    450   if (result == 0)
    451     ec = asio::error_code();
    452   return result;
    453 }
    454 
    455 bool sockatmark(socket_type s, asio::error_code& ec)
    456 {
    457   if (s == invalid_socket)
    458   {
    459     ec = asio::error::bad_descriptor;
    460     return false;
    461   }
    462 
    463 #if defined(SIOCATMARK)
    464   ioctl_arg_type value = 0;
    465   int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec);
    466   if (result == 0)
    467     ec = asio::error_code();
    468 # if defined(ENOTTY)
    469   if (ec.value() == ENOTTY)
    470     ec = asio::error::not_socket;
    471 # endif // defined(ENOTTY)
    472 #else // defined(SIOCATMARK)
    473   int value = error_wrapper(::sockatmark(s), ec);
    474   if (value != -1)
    475     ec = asio::error_code();
    476 #endif // defined(SIOCATMARK)
    477 
    478   return ec ? false : value != 0;
    479 }
    480 
    481 size_t available(socket_type s, asio::error_code& ec)
    482 {
    483   if (s == invalid_socket)
    484   {
    485     ec = asio::error::bad_descriptor;
    486     return 0;
    487   }
    488 
    489   ioctl_arg_type value = 0;
    490   int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec);
    491   if (result == 0)
    492     ec = asio::error_code();
    493 #if defined(ENOTTY)
    494   if (ec.value() == ENOTTY)
    495     ec = asio::error::not_socket;
    496 #endif // defined(ENOTTY)
    497 
    498   return ec ? static_cast<size_t>(0) : static_cast<size_t>(value);
    499 }
    500 
    501 int listen(socket_type s, int backlog, asio::error_code& ec)
    502 {
    503   if (s == invalid_socket)
    504   {
    505     ec = asio::error::bad_descriptor;
    506     return socket_error_retval;
    507   }
    508 
    509   clear_last_error();
    510   int result = error_wrapper(::listen(s, backlog), ec);
    511   if (result == 0)
    512     ec = asio::error_code();
    513   return result;
    514 }
    515 
    516 inline void init_buf_iov_base(void*& base, void* addr)
    517 {
    518   base = addr;
    519 }
    520 
    521 template <typename T>
    522 inline void init_buf_iov_base(T& base, void* addr)
    523 {
    524   base = static_cast<T>(addr);
    525 }
    526 
    527 typedef iovec buf;
    528 
    529 void init_buf(buf& b, void* data, size_t size)
    530 {
    531   init_buf_iov_base(b.iov_base, data);
    532   b.iov_len = size;
    533 }
    534 
    535 void init_buf(buf& b, const void* data, size_t size)
    536 {
    537   init_buf_iov_base(b.iov_base, const_cast<void*>(data));
    538   b.iov_len = size;
    539 }
    540 
    541 inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
    542 {
    543   name = addr;
    544 }
    545 
    546 inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
    547 {
    548   name = const_cast<socket_addr_type*>(addr);
    549 }
    550 
    551 template <typename T>
    552 inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
    553 {
    554   name = reinterpret_cast<T>(addr);
    555 }
    556 
    557 template <typename T>
    558 inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
    559 {
    560   name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
    561 }
    562 
    563 signed_size_type recv(socket_type s, buf* bufs, size_t count,
    564     int flags, asio::error_code& ec)
    565 {
    566   clear_last_error();
    567   msghdr msg = msghdr();
    568   msg.msg_iov = bufs;
    569   msg.msg_iovlen = static_cast<int>(count);
    570   signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
    571   if (result >= 0)
    572     ec = asio::error_code();
    573   return result;
    574 }
    575 
    576 size_t sync_recv(socket_type s, state_type state, buf* bufs,
    577     size_t count, int flags, bool all_empty, asio::error_code& ec)
    578 {
    579   if (s == invalid_socket)
    580   {
    581     ec = asio::error::bad_descriptor;
    582     return 0;
    583   }
    584 
    585   // A request to read 0 bytes on a stream is a no-op.
    586   if (all_empty && (state & stream_oriented))
    587   {
    588     ec = asio::error_code();
    589     return 0;
    590   }
    591 
    592   // Read some data.
    593   for (;;)
    594   {
    595     // Try to complete the operation without blocking.
    596     signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);
    597 
    598     // Check if operation succeeded.
    599     if (bytes > 0)
    600       return bytes;
    601 
    602     // Check for EOF.
    603     if ((state & stream_oriented) && bytes == 0)
    604     {
    605       ec = asio::error::eof;
    606       return 0;
    607     }
    608 
    609     // Operation failed.
    610     if ((state & user_set_non_blocking)
    611         || (ec != asio::error::would_block
    612           && ec != asio::error::try_again))
    613       return 0;
    614 
    615     // Wait for socket to become ready.
    616     if (socket_ops::poll_read(s, 0, ec) < 0)
    617       return 0;
    618   }
    619 }
    620 
    621 
    622 bool non_blocking_recv(socket_type s,
    623     buf* bufs, size_t count, int flags, bool is_stream,
    624     asio::error_code& ec, size_t& bytes_transferred)
    625 {
    626   for (;;)
    627   {
    628     // Read some data.
    629     signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);
    630 
    631     // Check for end of stream.
    632     if (is_stream && bytes == 0)
    633     {
    634       ec = asio::error::eof;
    635       return true;
    636     }
    637 
    638     // Retry operation if interrupted by signal.
    639     if (ec == asio::error::interrupted)
    640       continue;
    641 
    642     // Check if we need to run the operation again.
    643     if (ec == asio::error::would_block
    644         || ec == asio::error::try_again)
    645       return false;
    646 
    647     // Operation is complete.
    648     if (bytes >= 0)
    649     {
    650       ec = asio::error_code();
    651       bytes_transferred = bytes;
    652     }
    653     else
    654       bytes_transferred = 0;
    655 
    656     return true;
    657   }
    658 }
    659 
    660 
    661 signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
    662     int flags, socket_addr_type* addr, std::size_t* addrlen,
    663     asio::error_code& ec)
    664 {
    665   clear_last_error();
    666   msghdr msg = msghdr();
    667   init_msghdr_msg_name(msg.msg_name, addr);
    668   msg.msg_namelen = static_cast<int>(*addrlen);
    669   msg.msg_iov = bufs;
    670   msg.msg_iovlen = static_cast<int>(count);
    671   signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
    672   *addrlen = msg.msg_namelen;
    673   if (result >= 0)
    674     ec = asio::error_code();
    675   return result;
    676 }
    677 
    678 size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
    679     size_t count, int flags, socket_addr_type* addr,
    680     std::size_t* addrlen, asio::error_code& ec)
    681 {
    682   if (s == invalid_socket)
    683   {
    684     ec = asio::error::bad_descriptor;
    685     return 0;
    686   }
    687 
    688   // Read some data.
    689   for (;;)
    690   {
    691     // Try to complete the operation without blocking.
    692     signed_size_type bytes = socket_ops::recvfrom(
    693         s, bufs, count, flags, addr, addrlen, ec);
    694 
    695     // Check if operation succeeded.
    696     if (bytes >= 0)
    697       return bytes;
    698 
    699     // Operation failed.
    700     if ((state & user_set_non_blocking)
    701         || (ec != asio::error::would_block
    702           && ec != asio::error::try_again))
    703       return 0;
    704 
    705     // Wait for socket to become ready.
    706     if (socket_ops::poll_read(s, 0, ec) < 0)
    707       return 0;
    708   }
    709 }
    710 
    711 
    712 bool non_blocking_recvfrom(socket_type s,
    713     buf* bufs, size_t count, int flags,
    714     socket_addr_type* addr, std::size_t* addrlen,
    715     asio::error_code& ec, size_t& bytes_transferred)
    716 {
    717   for (;;)
    718   {
    719     // Read some data.
    720     signed_size_type bytes = socket_ops::recvfrom(
    721         s, bufs, count, flags, addr, addrlen, ec);
    722 
    723     // Retry operation if interrupted by signal.
    724     if (ec == asio::error::interrupted)
    725       continue;
    726 
    727     // Check if we need to run the operation again.
    728     if (ec == asio::error::would_block
    729         || ec == asio::error::try_again)
    730       return false;
    731 
    732     // Operation is complete.
    733     if (bytes >= 0)
    734     {
    735       ec = asio::error_code();
    736       bytes_transferred = bytes;
    737     }
    738     else
    739       bytes_transferred = 0;
    740 
    741     return true;
    742   }
    743 }
    744 
    745 
    746 signed_size_type recvmsg(socket_type s, buf* bufs, size_t count,
    747     int in_flags, int& out_flags, asio::error_code& ec)
    748 {
    749   clear_last_error();
    750   msghdr msg = msghdr();
    751   msg.msg_iov = bufs;
    752   msg.msg_iovlen = static_cast<int>(count);
    753   signed_size_type result = error_wrapper(::recvmsg(s, &msg, in_flags), ec);
    754   if (result >= 0)
    755   {
    756     ec = asio::error_code();
    757     out_flags = msg.msg_flags;
    758   }
    759   else
    760     out_flags = 0;
    761   return result;
    762 }
    763 
    764 size_t sync_recvmsg(socket_type s, state_type state,
    765     buf* bufs, size_t count, int in_flags, int& out_flags,
    766     asio::error_code& ec)
    767 {
    768   if (s == invalid_socket)
    769   {
    770     ec = asio::error::bad_descriptor;
    771     return 0;
    772   }
    773 
    774   // Read some data.
    775   for (;;)
    776   {
    777     // Try to complete the operation without blocking.
    778     signed_size_type bytes = socket_ops::recvmsg(
    779         s, bufs, count, in_flags, out_flags, ec);
    780 
    781     // Check if operation succeeded.
    782     if (bytes >= 0)
    783       return bytes;
    784 
    785     // Operation failed.
    786     if ((state & user_set_non_blocking)
    787         || (ec != asio::error::would_block
    788           && ec != asio::error::try_again))
    789       return 0;
    790 
    791     // Wait for socket to become ready.
    792     if (socket_ops::poll_read(s, 0, ec) < 0)
    793       return 0;
    794   }
    795 }
    796 
    797 
    798 bool non_blocking_recvmsg(socket_type s,
    799     buf* bufs, size_t count, int in_flags, int& out_flags,
    800     asio::error_code& ec, size_t& bytes_transferred)
    801 {
    802   for (;;)
    803   {
    804     // Read some data.
    805     signed_size_type bytes = socket_ops::recvmsg(
    806         s, bufs, count, in_flags, out_flags, ec);
    807 
    808     // Retry operation if interrupted by signal.
    809     if (ec == asio::error::interrupted)
    810       continue;
    811 
    812     // Check if we need to run the operation again.
    813     if (ec == asio::error::would_block
    814         || ec == asio::error::try_again)
    815       return false;
    816 
    817     // Operation is complete.
    818     if (bytes >= 0)
    819     {
    820       ec = asio::error_code();
    821       bytes_transferred = bytes;
    822     }
    823     else
    824       bytes_transferred = 0;
    825 
    826     return true;
    827   }
    828 }
    829 
    830 
    831 signed_size_type send(socket_type s, const buf* bufs, size_t count,
    832     int flags, asio::error_code& ec)
    833 {
    834   clear_last_error();
    835   msghdr msg = msghdr();
    836   msg.msg_iov = const_cast<buf*>(bufs);
    837   msg.msg_iovlen = static_cast<int>(count);
    838 #if defined(__linux__)
    839   flags |= MSG_NOSIGNAL;
    840 #endif // defined(__linux__)
    841   signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec);
    842   if (result >= 0)
    843     ec = asio::error_code();
    844   return result;
    845 }
    846 
    847 size_t sync_send(socket_type s, state_type state, const buf* bufs,
    848     size_t count, int flags, bool all_empty, asio::error_code& ec)
    849 {
    850   if (s == invalid_socket)
    851   {
    852     ec = asio::error::bad_descriptor;
    853     return 0;
    854   }
    855 
    856   // A request to write 0 bytes to a stream is a no-op.
    857   if (all_empty && (state & stream_oriented))
    858   {
    859     ec = asio::error_code();
    860     return 0;
    861   }
    862 
    863   // Read some data.
    864   for (;;)
    865   {
    866     // Try to complete the operation without blocking.
    867     signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec);
    868 
    869     // Check if operation succeeded.
    870     if (bytes >= 0)
    871       return bytes;
    872 
    873     // Operation failed.
    874     if ((state & user_set_non_blocking)
    875         || (ec != asio::error::would_block
    876           && ec != asio::error::try_again))
    877       return 0;
    878 
    879     // Wait for socket to become ready.
    880     if (socket_ops::poll_write(s, 0, ec) < 0)
    881       return 0;
    882   }
    883 }
    884 
    885 
    886 bool non_blocking_send(socket_type s,
    887     const buf* bufs, size_t count, int flags,
    888     asio::error_code& ec, size_t& bytes_transferred)
    889 {
    890   for (;;)
    891   {
    892     // Write some data.
    893     signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec);
    894 
    895     // Retry operation if interrupted by signal.
    896     if (ec == asio::error::interrupted)
    897       continue;
    898 
    899     // Check if we need to run the operation again.
    900     if (ec == asio::error::would_block
    901         || ec == asio::error::try_again)
    902       return false;
    903 
    904     // Operation is complete.
    905     if (bytes >= 0)
    906     {
    907       ec = asio::error_code();
    908       bytes_transferred = bytes;
    909     }
    910     else
    911       bytes_transferred = 0;
    912 
    913     return true;
    914   }
    915 }
    916 
    917 
    918 signed_size_type sendto(socket_type s, const buf* bufs, size_t count,
    919     int flags, const socket_addr_type* addr, std::size_t addrlen,
    920     asio::error_code& ec)
    921 {
    922   clear_last_error();
    923   msghdr msg = msghdr();
    924   init_msghdr_msg_name(msg.msg_name, addr);
    925   msg.msg_namelen = static_cast<int>(addrlen);
    926   msg.msg_iov = const_cast<buf*>(bufs);
    927   msg.msg_iovlen = static_cast<int>(count);
    928 #if defined(__linux__)
    929   flags |= MSG_NOSIGNAL;
    930 #endif // defined(__linux__)
    931   signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec);
    932   if (result >= 0)
    933     ec = asio::error_code();
    934   return result;
    935 }
    936 
    937 size_t sync_sendto(socket_type s, state_type state, const buf* bufs,
    938     size_t count, int flags, const socket_addr_type* addr,
    939     std::size_t addrlen, asio::error_code& ec)
    940 {
    941   if (s == invalid_socket)
    942   {
    943     ec = asio::error::bad_descriptor;
    944     return 0;
    945   }
    946 
    947   // Write some data.
    948   for (;;)
    949   {
    950     // Try to complete the operation without blocking.
    951     signed_size_type bytes = socket_ops::sendto(
    952         s, bufs, count, flags, addr, addrlen, ec);
    953 
    954     // Check if operation succeeded.
    955     if (bytes >= 0)
    956       return bytes;
    957 
    958     // Operation failed.
    959     if ((state & user_set_non_blocking)
    960         || (ec != asio::error::would_block
    961           && ec != asio::error::try_again))
    962       return 0;
    963 
    964     // Wait for socket to become ready.
    965     if (socket_ops::poll_write(s, 0, ec) < 0)
    966       return 0;
    967   }
    968 }
    969 
    970 
    971 bool non_blocking_sendto(socket_type s,
    972     const buf* bufs, size_t count, int flags,
    973     const socket_addr_type* addr, std::size_t addrlen,
    974     asio::error_code& ec, size_t& bytes_transferred)
    975 {
    976   for (;;)
    977   {
    978     // Write some data.
    979     signed_size_type bytes = socket_ops::sendto(
    980         s, bufs, count, flags, addr, addrlen, ec);
    981 
    982     // Retry operation if interrupted by signal.
    983     if (ec == asio::error::interrupted)
    984       continue;
    985 
    986     // Check if we need to run the operation again.
    987     if (ec == asio::error::would_block
    988         || ec == asio::error::try_again)
    989       return false;
    990 
    991     // Operation is complete.
    992     if (bytes >= 0)
    993     {
    994       ec = asio::error_code();
    995       bytes_transferred = bytes;
    996     }
    997     else
    998       bytes_transferred = 0;
    999 
   1000     return true;
   1001   }
   1002 }
   1003 
   1004 
   1005 socket_type socket(int af, int type, int protocol,
   1006     asio::error_code& ec)
   1007 {
   1008   clear_last_error();
   1009 #if   defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
   1010   socket_type s = error_wrapper(::socket(af, type, protocol), ec);
   1011   if (s == invalid_socket)
   1012     return s;
   1013 
   1014   int optval = 1;
   1015   int result = error_wrapper(::setsockopt(s,
   1016         SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
   1017   if (result != 0)
   1018   {
   1019     ::close(s);
   1020     return invalid_socket;
   1021   }
   1022 
   1023   return s;
   1024 #else
   1025   int s = error_wrapper(::socket(af, type, protocol), ec);
   1026   if (s >= 0)
   1027     ec = asio::error_code();
   1028   return s;
   1029 #endif
   1030 }
   1031 
   1032 template <typename SockLenType>
   1033 inline int call_setsockopt(SockLenType msghdr::*,
   1034     socket_type s, int level, int optname,
   1035     const void* optval, std::size_t optlen)
   1036 {
   1037   return ::setsockopt(s, level, optname,
   1038       (const char*)optval, (SockLenType)optlen);
   1039 }
   1040 
   1041 int setsockopt(socket_type s, state_type& state, int level, int optname,
   1042     const void* optval, std::size_t optlen, asio::error_code& ec)
   1043 {
   1044   if (s == invalid_socket)
   1045   {
   1046     ec = asio::error::bad_descriptor;
   1047     return socket_error_retval;
   1048   }
   1049 
   1050   if (level == custom_socket_option_level && optname == always_fail_option)
   1051   {
   1052     ec = asio::error::invalid_argument;
   1053     return socket_error_retval;
   1054   }
   1055 
   1056   if (level == custom_socket_option_level
   1057       && optname == enable_connection_aborted_option)
   1058   {
   1059     if (optlen != sizeof(int))
   1060     {
   1061       ec = asio::error::invalid_argument;
   1062       return socket_error_retval;
   1063     }
   1064 
   1065     if (*static_cast<const int*>(optval))
   1066       state |= enable_connection_aborted;
   1067     else
   1068       state &= ~enable_connection_aborted;
   1069     ec = asio::error_code();
   1070     return 0;
   1071   }
   1072 
   1073   if (level == SOL_SOCKET && optname == SO_LINGER)
   1074     state |= user_set_linger;
   1075 
   1076   clear_last_error();
   1077   int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
   1078         s, level, optname, optval, optlen), ec);
   1079   if (result == 0)
   1080   {
   1081     ec = asio::error_code();
   1082 
   1083 #if defined(__MACH__) && defined(__APPLE__)    || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
   1084     // To implement portable behaviour for SO_REUSEADDR with UDP sockets we
   1085     // need to also set SO_REUSEPORT on BSD-based platforms.
   1086     if ((state & datagram_oriented)
   1087         && level == SOL_SOCKET && optname == SO_REUSEADDR)
   1088     {
   1089       call_setsockopt(&msghdr::msg_namelen, s,
   1090           SOL_SOCKET, SO_REUSEPORT, optval, optlen);
   1091     }
   1092 #endif
   1093   }
   1094 
   1095   return result;
   1096 }
   1097 
   1098 template <typename SockLenType>
   1099 inline int call_getsockopt(SockLenType msghdr::*,
   1100     socket_type s, int level, int optname,
   1101     void* optval, std::size_t* optlen)
   1102 {
   1103   SockLenType tmp_optlen = (SockLenType)*optlen;
   1104   int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
   1105   *optlen = (std::size_t)tmp_optlen;
   1106   return result;
   1107 }
   1108 
   1109 int getsockopt(socket_type s, state_type state, int level, int optname,
   1110     void* optval, size_t* optlen, asio::error_code& ec)
   1111 {
   1112   if (s == invalid_socket)
   1113   {
   1114     ec = asio::error::bad_descriptor;
   1115     return socket_error_retval;
   1116   }
   1117 
   1118   if (level == custom_socket_option_level && optname == always_fail_option)
   1119   {
   1120     ec = asio::error::invalid_argument;
   1121     return socket_error_retval;
   1122   }
   1123 
   1124   if (level == custom_socket_option_level
   1125       && optname == enable_connection_aborted_option)
   1126   {
   1127     if (*optlen != sizeof(int))
   1128     {
   1129       ec = asio::error::invalid_argument;
   1130       return socket_error_retval;
   1131     }
   1132 
   1133     *static_cast<int*>(optval) = (state & enable_connection_aborted) ? 1 : 0;
   1134     ec = asio::error_code();
   1135     return 0;
   1136   }
   1137 
   1138   clear_last_error();
   1139   int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
   1140         s, level, optname, optval, optlen), ec);
   1141 #if defined(__linux__)
   1142   if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
   1143       && (optname == SO_SNDBUF || optname == SO_RCVBUF))
   1144   {
   1145     // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel
   1146     // to set the buffer size to N*2. Linux puts additional stuff into the
   1147     // buffers so that only about half is actually available to the application.
   1148     // The retrieved value is divided by 2 here to make it appear as though the
   1149     // correct value has been set.
   1150     *static_cast<int*>(optval) /= 2;
   1151   }
   1152 #endif // defined(__linux__)
   1153   if (result == 0)
   1154     ec = asio::error_code();
   1155   return result;
   1156 }
   1157 
   1158 template <typename SockLenType>
   1159 inline int call_getpeername(SockLenType msghdr::*,
   1160     socket_type s, socket_addr_type* addr, std::size_t* addrlen)
   1161 {
   1162   SockLenType tmp_addrlen = (SockLenType)*addrlen;
   1163   int result = ::getpeername(s, addr, &tmp_addrlen);
   1164   *addrlen = (std::size_t)tmp_addrlen;
   1165   return result;
   1166 }
   1167 
   1168 int getpeername(socket_type s, socket_addr_type* addr,
   1169     std::size_t* addrlen, bool cached, asio::error_code& ec)
   1170 {
   1171   if (s == invalid_socket)
   1172   {
   1173     ec = asio::error::bad_descriptor;
   1174     return socket_error_retval;
   1175   }
   1176 
   1177   (void)cached;
   1178 
   1179   clear_last_error();
   1180   int result = error_wrapper(call_getpeername(
   1181         &msghdr::msg_namelen, s, addr, addrlen), ec);
   1182   if (result == 0)
   1183     ec = asio::error_code();
   1184   return result;
   1185 }
   1186 
   1187 template <typename SockLenType>
   1188 inline int call_getsockname(SockLenType msghdr::*,
   1189     socket_type s, socket_addr_type* addr, std::size_t* addrlen)
   1190 {
   1191   SockLenType tmp_addrlen = (SockLenType)*addrlen;
   1192   int result = ::getsockname(s, addr, &tmp_addrlen);
   1193   *addrlen = (std::size_t)tmp_addrlen;
   1194   return result;
   1195 }
   1196 
   1197 int getsockname(socket_type s, socket_addr_type* addr,
   1198     std::size_t* addrlen, asio::error_code& ec)
   1199 {
   1200   if (s == invalid_socket)
   1201   {
   1202     ec = asio::error::bad_descriptor;
   1203     return socket_error_retval;
   1204   }
   1205 
   1206   clear_last_error();
   1207   int result = error_wrapper(call_getsockname(
   1208         &msghdr::msg_namelen, s, addr, addrlen), ec);
   1209   if (result == 0)
   1210     ec = asio::error_code();
   1211   return result;
   1212 }
   1213 
   1214 int ioctl(socket_type s, state_type& state, int cmd,
   1215     ioctl_arg_type* arg, asio::error_code& ec)
   1216 {
   1217   if (s == invalid_socket)
   1218   {
   1219     ec = asio::error::bad_descriptor;
   1220     return socket_error_retval;
   1221   }
   1222 
   1223   clear_last_error();
   1224 #if   defined(__MACH__) && defined(__APPLE__)    || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
   1225   int result = error_wrapper(::ioctl(s,
   1226         static_cast<unsigned int>(cmd), arg), ec);
   1227 #else
   1228   int result = error_wrapper(::ioctl(s, cmd, arg), ec);
   1229 #endif
   1230   if (result >= 0)
   1231   {
   1232     ec = asio::error_code();
   1233 
   1234     // When updating the non-blocking mode we always perform the ioctl syscall,
   1235     // even if the flags would otherwise indicate that the socket is already in
   1236     // the correct state. This ensures that the underlying socket is put into
   1237     // the state that has been requested by the user. If the ioctl syscall was
   1238     // successful then we need to update the flags to match.
   1239     if (cmd == static_cast<int>(FIONBIO))
   1240     {
   1241       if (*arg)
   1242       {
   1243         state |= user_set_non_blocking;
   1244       }
   1245       else
   1246       {
   1247         // Clearing the non-blocking mode always overrides any internally-set
   1248         // non-blocking flag. Any subsequent asynchronous operations will need
   1249         // to re-enable non-blocking I/O.
   1250         state &= ~(user_set_non_blocking | internal_non_blocking);
   1251       }
   1252     }
   1253   }
   1254 
   1255   return result;
   1256 }
   1257 
   1258 int select(int nfds, fd_set* readfds, fd_set* writefds,
   1259     fd_set* exceptfds, timeval* timeout, asio::error_code& ec)
   1260 {
   1261   clear_last_error();
   1262 
   1263 #if defined(__hpux) && defined(__SELECT)
   1264   timespec ts;
   1265   ts.tv_sec = timeout ? timeout->tv_sec : 0;
   1266   ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
   1267   return error_wrapper(::pselect(nfds, readfds,
   1268         writefds, exceptfds, timeout ? &ts : 0, 0), ec);
   1269 #else
   1270   int result = error_wrapper(::select(nfds, readfds,
   1271         writefds, exceptfds, timeout), ec);
   1272   if (result >= 0)
   1273     ec = asio::error_code();
   1274   return result;
   1275 #endif
   1276 }
   1277 
   1278 int poll_read(socket_type s, state_type state, asio::error_code& ec)
   1279 {
   1280   if (s == invalid_socket)
   1281   {
   1282     ec = asio::error::bad_descriptor;
   1283     return socket_error_retval;
   1284   }
   1285 
   1286       // || defined(__CYGWIN__)
   1287       // || defined(__SYMBIAN32__)
   1288   pollfd fds;
   1289   fds.fd = s;
   1290   fds.events = POLLIN;
   1291   fds.revents = 0;
   1292   int timeout = (state & user_set_non_blocking) ? 0 : -1;
   1293   clear_last_error();
   1294   int result = error_wrapper(::poll(&fds, 1, timeout), ec);
   1295        // || defined(__CYGWIN__)
   1296        // || defined(__SYMBIAN32__)
   1297   if (result == 0)
   1298     ec = (state & user_set_non_blocking)
   1299       ? asio::error::would_block : asio::error_code();
   1300   else if (result > 0)
   1301     ec = asio::error_code();
   1302   return result;
   1303 }
   1304 
   1305 int poll_write(socket_type s, state_type state, asio::error_code& ec)
   1306 {
   1307   if (s == invalid_socket)
   1308   {
   1309     ec = asio::error::bad_descriptor;
   1310     return socket_error_retval;
   1311   }
   1312 
   1313       // || defined(__CYGWIN__)
   1314       // || defined(__SYMBIAN32__)
   1315   pollfd fds;
   1316   fds.fd = s;
   1317   fds.events = POLLOUT;
   1318   fds.revents = 0;
   1319   int timeout = (state & user_set_non_blocking) ? 0 : -1;
   1320   clear_last_error();
   1321   int result = error_wrapper(::poll(&fds, 1, timeout), ec);
   1322        // || defined(__CYGWIN__)
   1323        // || defined(__SYMBIAN32__)
   1324   if (result == 0)
   1325     ec = (state & user_set_non_blocking)
   1326       ? asio::error::would_block : asio::error_code();
   1327   else if (result > 0)
   1328     ec = asio::error_code();
   1329   return result;
   1330 }
   1331 
   1332 int poll_connect(socket_type s, asio::error_code& ec)
   1333 {
   1334   if (s == invalid_socket)
   1335   {
   1336     ec = asio::error::bad_descriptor;
   1337     return socket_error_retval;
   1338   }
   1339 
   1340       // || defined(__CYGWIN__)
   1341       // || defined(__SYMBIAN32__)
   1342   pollfd fds;
   1343   fds.fd = s;
   1344   fds.events = POLLOUT;
   1345   fds.revents = 0;
   1346   clear_last_error();
   1347   int result = error_wrapper(::poll(&fds, 1, -1), ec);
   1348   if (result >= 0)
   1349     ec = asio::error_code();
   1350   return result;
   1351        // || defined(__CYGWIN__)
   1352        // || defined(__SYMBIAN32__)
   1353 }
   1354 
   1355 
   1356 const char* inet_ntop(int af, const void* src, char* dest, size_t length,
   1357     unsigned long scope_id, asio::error_code& ec)
   1358 {
   1359   clear_last_error();
   1360   const char* result = error_wrapper(::inet_ntop(
   1361         af, src, dest, static_cast<int>(length)), ec);
   1362   if (result == 0 && !ec)
   1363     ec = asio::error::invalid_argument;
   1364   if (result != 0 && af == ASIO_OS_DEF(AF_INET6) && scope_id != 0)
   1365   {
   1366     using namespace std; // For strcat and sprintf.
   1367     char if_name[IF_NAMESIZE + 1] = "%";
   1368     const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src);
   1369     bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe)
   1370         && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80));
   1371     bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff)
   1372         && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02));
   1373     if ((!is_link_local && !is_multicast_link_local)
   1374         || if_indextoname(static_cast<unsigned>(scope_id), if_name + 1) == 0)
   1375       sprintf(if_name + 1, "%lu", scope_id);
   1376     strcat(dest, if_name);
   1377   }
   1378   return result;
   1379 }
   1380 
   1381 int inet_pton(int af, const char* src, void* dest,
   1382     unsigned long* scope_id, asio::error_code& ec)
   1383 {
   1384   clear_last_error();
   1385   using namespace std; // For strchr, memcpy and atoi.
   1386 
   1387   // On some platforms, inet_pton fails if an address string contains a scope
   1388   // id. Detect and remove the scope id before passing the string to inet_pton.
   1389   const bool is_v6 = (af == ASIO_OS_DEF(AF_INET6));
   1390   const char* if_name = is_v6 ? strchr(src, '%') : 0;
   1391   char src_buf[max_addr_v6_str_len + 1];
   1392   const char* src_ptr = src;
   1393   if (if_name != 0)
   1394   {
   1395     if (if_name - src > max_addr_v6_str_len)
   1396     {
   1397       ec = asio::error::invalid_argument;
   1398       return 0;
   1399     }
   1400     memcpy(src_buf, src, if_name - src);
   1401     src_buf[if_name - src] = 0;
   1402     src_ptr = src_buf;
   1403   }
   1404 
   1405   int result = error_wrapper(::inet_pton(af, src_ptr, dest), ec);
   1406   if (result <= 0 && !ec)
   1407     ec = asio::error::invalid_argument;
   1408   if (result > 0 && is_v6 && scope_id)
   1409   {
   1410     using namespace std; // For strchr and atoi.
   1411     *scope_id = 0;
   1412     if (if_name != 0)
   1413     {
   1414       in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest);
   1415       bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe)
   1416           && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80));
   1417       bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff)
   1418           && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02));
   1419       if (is_link_local || is_multicast_link_local)
   1420         *scope_id = if_nametoindex(if_name + 1);
   1421       if (*scope_id == 0)
   1422         *scope_id = atoi(if_name + 1);
   1423     }
   1424   }
   1425   return result;
   1426 }
   1427 
   1428 int gethostname(char* name, int namelen, asio::error_code& ec)
   1429 {
   1430   clear_last_error();
   1431   int result = error_wrapper(::gethostname(name, namelen), ec);
   1432   return result;
   1433 }
   1434 
   1435 
   1436 
   1437 inline asio::error_code translate_addrinfo_error(int error)
   1438 {
   1439   switch (error)
   1440   {
   1441   case 0:
   1442     return asio::error_code();
   1443   case EAI_AGAIN:
   1444     return asio::error::host_not_found_try_again;
   1445   case EAI_BADFLAGS:
   1446     return asio::error::invalid_argument;
   1447   case EAI_FAIL:
   1448     return asio::error::no_recovery;
   1449   case EAI_FAMILY:
   1450     return asio::error::address_family_not_supported;
   1451   case EAI_MEMORY:
   1452     return asio::error::no_memory;
   1453   case EAI_NONAME:
   1454 #if defined(EAI_ADDRFAMILY)
   1455   case EAI_ADDRFAMILY:
   1456 #endif
   1457 #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
   1458   case EAI_NODATA:
   1459 #endif
   1460     return asio::error::host_not_found;
   1461   case EAI_SERVICE:
   1462     return asio::error::service_not_found;
   1463   case EAI_SOCKTYPE:
   1464     return asio::error::socket_type_not_supported;
   1465   default: // Possibly the non-portable EAI_SYSTEM.
   1466     return asio::error_code(
   1467         errno, asio::error::get_system_category());
   1468   }
   1469 }
   1470 
   1471 asio::error_code getaddrinfo(const char* host,
   1472     const char* service, const addrinfo_type& hints,
   1473     addrinfo_type** result, asio::error_code& ec)
   1474 {
   1475   host = (host && *host) ? host : 0;
   1476   service = (service && *service) ? service : 0;
   1477   clear_last_error();
   1478   int error = ::getaddrinfo(host, service, &hints, result);
   1479   return ec = translate_addrinfo_error(error);
   1480 }
   1481 
   1482 asio::error_code background_getaddrinfo(
   1483     const weak_cancel_token_type& cancel_token, const char* host,
   1484     const char* service, const addrinfo_type& hints,
   1485     addrinfo_type** result, asio::error_code& ec)
   1486 {
   1487   if (cancel_token.expired())
   1488     ec = asio::error::operation_aborted;
   1489   else
   1490     socket_ops::getaddrinfo(host, service, hints, result, ec);
   1491   return ec;
   1492 }
   1493 
   1494 void freeaddrinfo(addrinfo_type* ai)
   1495 {
   1496   ::freeaddrinfo(ai);
   1497 }
   1498 
   1499 asio::error_code getnameinfo(const socket_addr_type* addr,
   1500     std::size_t addrlen, char* host, std::size_t hostlen,
   1501     char* serv, std::size_t servlen, int flags, asio::error_code& ec)
   1502 {
   1503   clear_last_error();
   1504   int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
   1505   return ec = translate_addrinfo_error(error);
   1506 }
   1507 
   1508 asio::error_code sync_getnameinfo(
   1509     const socket_addr_type* addr, std::size_t addrlen,
   1510     char* host, std::size_t hostlen, char* serv,
   1511     std::size_t servlen, int sock_type, asio::error_code& ec)
   1512 {
   1513   // First try resolving with the service name. If that fails try resolving
   1514   // but allow the service to be returned as a number.
   1515   int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
   1516   socket_ops::getnameinfo(addr, addrlen, host,
   1517       hostlen, serv, servlen, flags, ec);
   1518   if (ec)
   1519   {
   1520     socket_ops::getnameinfo(addr, addrlen, host, hostlen,
   1521         serv, servlen, flags | NI_NUMERICSERV, ec);
   1522   }
   1523 
   1524   return ec;
   1525 }
   1526 
   1527 asio::error_code background_getnameinfo(
   1528     const weak_cancel_token_type& cancel_token,
   1529     const socket_addr_type* addr, std::size_t addrlen,
   1530     char* host, std::size_t hostlen, char* serv,
   1531     std::size_t servlen, int sock_type, asio::error_code& ec)
   1532 {
   1533   if (cancel_token.expired())
   1534   {
   1535     ec = asio::error::operation_aborted;
   1536   }
   1537   else
   1538   {
   1539     // First try resolving with the service name. If that fails try resolving
   1540     // but allow the service to be returned as a number.
   1541     int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
   1542     socket_ops::getnameinfo(addr, addrlen, host,
   1543         hostlen, serv, servlen, flags, ec);
   1544     if (ec)
   1545     {
   1546       socket_ops::getnameinfo(addr, addrlen, host, hostlen,
   1547           serv, servlen, flags | NI_NUMERICSERV, ec);
   1548     }
   1549   }
   1550 
   1551   return ec;
   1552 }
   1553 
   1554 
   1555 u_long_type network_to_host_long(u_long_type value)
   1556 {
   1557   return ntohl(value);
   1558 }
   1559 
   1560 u_long_type host_to_network_long(u_long_type value)
   1561 {
   1562   return htonl(value);
   1563 }
   1564 
   1565 u_short_type network_to_host_short(u_short_type value)
   1566 {
   1567   return ntohs(value);
   1568 }
   1569 
   1570 u_short_type host_to_network_short(u_short_type value)
   1571 {
   1572   return htons(value);
   1573 }
   1574 
   1575 } // namespace socket_ops
   1576 } // namespace detail
   1577 } // namespace asio
   1578 
   1579 #include "asio/detail/pop_options.hpp"
   1580 
   1581 #endif // ASIO_DETAIL_SOCKET_OPS_IPP
   1582