PageRenderTime 48ms CodeModel.GetById 31ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/asio/detail/impl/socket_ops.ipp

http://hadesmem.googlecode.com/
C++ Header | 3048 lines | 2550 code | 287 blank | 211 comment | 765 complexity | a110c3cf3a01d0363e2dff13e1d4da07 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file