⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket_ops.hpp

📁 这是国外的resip协议栈
💻 HPP
📖 第 1 页 / 共 4 页
字号:
  if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))  {    typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*);    if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt"))    {      clear_error(ec);      int tmp_optlen = static_cast<int>(*optlen);      int result = error_wrapper(gso(s, level, optname,            reinterpret_cast<char*>(optval), &tmp_optlen), ec);      *optlen = static_cast<size_t>(tmp_optlen);      if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY          && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))      {        // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are        // only supported on Windows Vista and later. To simplify program logic        // we will fake success of getting this option and specify that the        // value is non-zero (i.e. true). This corresponds to the behavior of        // IPv6 sockets on Windows platforms pre-Vista.        *static_cast<DWORD*>(optval) = 1;        clear_error(ec);      }      return result;    }  }  ec = asio::error::fault;  return -1;#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)  clear_error(ec);  int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,        s, level, optname, optval, optlen), ec);  if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY      && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))  {    // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only    // supported on Windows Vista and later. To simplify program logic we will    // fake success of getting this option and specify that the value is    // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets    // on Windows platforms pre-Vista.    *static_cast<DWORD*>(optval) = 1;    clear_error(ec);  }# if defined(UNDER_CE)  if (result == 0)    clear_error(ec);# endif  return result;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  clear_error(ec);  int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,        s, level, optname, optval, optlen), ec);#if defined(__linux__)  if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)      && (optname == SO_SNDBUF || optname == SO_RCVBUF))  {    // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel    // to set the buffer size to N*2. Linux puts additional stuff into the    // buffers so that only about half is actually available to the application.    // The retrieved value is divided by 2 here to make it appear as though the    // correct value has been set.    *static_cast<int*>(optval) /= 2;  }#endif // defined(__linux__)  return result;#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}template <typename SockLenType>inline int call_getpeername(SockLenType msghdr::*,    socket_type s, socket_addr_type* addr, std::size_t* addrlen){  SockLenType tmp_addrlen = (SockLenType)*addrlen;  int result = ::getpeername(s, addr, &tmp_addrlen);  *addrlen = (std::size_t)tmp_addrlen;  return result;}inline int getpeername(socket_type s, socket_addr_type* addr,    std::size_t* addrlen, asio::error_code& ec){  clear_error(ec);  int result = error_wrapper(call_getpeername(        &msghdr::msg_namelen, s, addr, addrlen), ec);#if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result == 0)    clear_error(ec);#endif  return result;}template <typename SockLenType>inline int call_getsockname(SockLenType msghdr::*,    socket_type s, socket_addr_type* addr, std::size_t* addrlen){  SockLenType tmp_addrlen = (SockLenType)*addrlen;  int result = ::getsockname(s, addr, &tmp_addrlen);  *addrlen = (std::size_t)tmp_addrlen;  return result;}inline int getsockname(socket_type s, socket_addr_type* addr,    std::size_t* addrlen, asio::error_code& ec){  clear_error(ec);  int result = error_wrapper(call_getsockname(        &msghdr::msg_namelen, s, addr, addrlen), ec);#if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result == 0)    clear_error(ec);#endif  return result;}inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,    asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec);# if defined(UNDER_CE)  if (result == 0)    clear_error(ec);# endif  return result;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  return error_wrapper(::ioctl(s, cmd, arg), ec);#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline int select(int nfds, fd_set* readfds, fd_set* writefds,    fd_set* exceptfds, timeval* timeout, asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  if (!readfds && !writefds && !exceptfds && timeout)  {    DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;    if (milliseconds == 0)      milliseconds = 1; // Force context switch.    ::Sleep(milliseconds);    ec = asio::error_code();    return 0;  }  // The select() call allows timeout values measured in microseconds, but the  // system clock (as wrapped by boost::posix_time::microsec_clock) typically  // has a resolution of 10 milliseconds. This can lead to a spinning select  // reactor, meaning increased CPU usage, when waiting for the earliest  // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight  // spin we'll use a minimum timeout of 1 millisecond.  if (timeout && timeout->tv_sec == 0      && timeout->tv_usec > 0 && timeout->tv_usec < 1000)    timeout->tv_usec = 1000;#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)#if defined(__hpux) && defined(__HP_aCC)  timespec ts;  ts.tv_sec = timeout ? timeout->tv_sec : 0;  ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;  return error_wrapper(::pselect(nfds, readfds,        writefds, exceptfds, timeout ? &ts : 0, 0), ec);#else  int result = error_wrapper(::select(nfds, readfds,        writefds, exceptfds, timeout), ec);# if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result >= 0)    clear_error(ec);# endif  return result;#endif}inline int poll_read(socket_type s, asio::error_code& ec){#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  FD_SET fds;  FD_ZERO(&fds);  FD_SET(s, &fds);  clear_error(ec);  int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec);# if defined(UNDER_CE)  if (result >= 0)    clear_error(ec);# endif  return result;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  pollfd fds;  fds.fd = s;  fds.events = POLLIN;  fds.revents = 0;  clear_error(ec);  return error_wrapper(::poll(&fds, 1, -1), ec);#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline int poll_write(socket_type s, asio::error_code& ec){#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  FD_SET fds;  FD_ZERO(&fds);  FD_SET(s, &fds);  clear_error(ec);  int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec);# if defined(UNDER_CE)  if (result >= 0)    clear_error(ec);# endif  return result;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  pollfd fds;  fds.fd = s;  fds.events = POLLOUT;  fds.revents = 0;  clear_error(ec);  return error_wrapper(::poll(&fds, 1, -1), ec);#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline const char* inet_ntop(int af, const void* src, char* dest, size_t length,    unsigned long scope_id, asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  using namespace std; // For memcpy.  if (af != AF_INET && af != AF_INET6)  {    ec = asio::error::address_family_not_supported;    return 0;  }  sockaddr_storage_type address;  DWORD address_length;  if (af == AF_INET)  {    address_length = sizeof(sockaddr_in4_type);    sockaddr_in4_type* ipv4_address =      reinterpret_cast<sockaddr_in4_type*>(&address);    ipv4_address->sin_family = AF_INET;    ipv4_address->sin_port = 0;    memcpy(&ipv4_address->sin_addr, src, sizeof(in4_addr_type));  }  else // AF_INET6  {    address_length = sizeof(sockaddr_in6_type);    sockaddr_in6_type* ipv6_address =      reinterpret_cast<sockaddr_in6_type*>(&address);    ipv6_address->sin6_family = AF_INET6;    ipv6_address->sin6_port = 0;    ipv6_address->sin6_flowinfo = 0;    ipv6_address->sin6_scope_id = scope_id;    memcpy(&ipv6_address->sin6_addr, src, sizeof(in6_addr_type));  }  DWORD string_length = static_cast<DWORD>(length);#if defined(BOOST_NO_ANSI_APIS)  LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR));  int result = error_wrapper(::WSAAddressToStringW(        reinterpret_cast<sockaddr*>(&address),        address_length, 0, string_buffer, &string_length), ec);  ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0);#else  int result = error_wrapper(::WSAAddressToStringA(        reinterpret_cast<sockaddr*>(&address),        address_length, 0, dest, &string_length), ec);#endif  // Windows may set error code on success.  if (result != socket_error_retval)    clear_error(ec);  // Windows may not set an error code on failure.  else if (result == socket_error_retval && !ec)    ec = asio::error::invalid_argument;  return result == socket_error_retval ? 0 : dest;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec);  if (result == 0 && !ec)    ec = asio::error::invalid_argument;  if (result != 0 && af == AF_INET6 && scope_id != 0)  {    using namespace std; // For strcat and sprintf.    char if_name[IF_NAMESIZE + 1] = "%";    const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src);    bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address);    if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0)      sprintf(if_name + 1, "%lu", scope_id);    strcat(dest, if_name);  }  return result;#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline int inet_pton(int af, const char* src, void* dest,    unsigned long* scope_id, asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  using namespace std; // For memcpy and strcmp.  if (af != AF_INET && af != AF_INET6)  {    ec = asio::error::address_family_not_supported;    return -1;  }  sockaddr_storage_type address;  int address_length = sizeof(sockaddr_storage_type);#if defined(BOOST_NO_ANSI_APIS)  int num_wide_chars = strlen(src) + 1;  LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR));  ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars);  int result = error_wrapper(::WSAStringToAddressW(        wide_buffer, af, 0,        reinterpret_cast<sockaddr*>(&address),        &address_length), ec);#else  int result = error_wrapper(::WSAStringToAddressA(        const_cast<char*>(src), af, 0,        reinterpret_cast<sockaddr*>(&address),        &address_length), ec);#endif  if (af == AF_INET)  {    if (result != socket_error_retval)    {      sockaddr_in4_type* ipv4_address =        reinterpret_cast<sockaddr_in4_type*>(&address);      memcpy(dest, &ipv4_address->sin_addr, sizeof(in4_addr_type));      clear_error(ec);    }    else if (strcmp(src, "255.255.255.255") == 0)    {      static_cast<in4_addr_type*>(dest)->s_addr = INADDR_NONE;      clear_error(ec);    }  }  else // AF_INET6  {    if (result != socket_error_retval)    {      sockaddr_in6_type* ipv6_address =        reinterpret_cast<sockaddr_in6_type*>(&address);      memcpy(dest, &ipv6_address->sin6_addr, sizeof(in6_addr_type));      if (scope_id)        *scope_id = ipv6_address->sin6_scope_id;      clear_error(ec);    }  }  // Windows may not set an error code on failure.  if (result == socket_error_retval && !ec)    ec = asio::error::invalid_argument;#if defined(UNDER_CE)  if (result != socket_error_retval)    clear_error(ec);#endif  return result == socket_error_retval ? -1 : 1;#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)  int result = error_wrapper(::inet_pton(af, src, dest), ec);  if (result <= 0 && !ec)    ec = asio::error::invalid_argument;  if (result > 0 && af == AF_INET6 && scope_id)  {    using namespace std; // For strchr and atoi.    *scope_id = 0;    if (const char* if_name = strchr(src, '%'))    {      in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest);      bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address);      if (is_link_local)        *scope_id = if_nametoindex(if_name + 1);      if (*scope_id == 0)        *scope_id = atoi(if_name + 1);    }  }  return result;#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)}inline int gethostname(char* name, int namelen, asio::error_code& ec){  clear_error(ec);  int result = error_wrapper(::gethostname(name, namelen), ec);#if defined(BOOST_WINDOWS) && defined(UNDER_CE)  if (result == 0)    clear_error(ec);#endif  return result;}#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \  || defined(__MACH__) && defined(__APPLE__)// The following functions are only needed for emulation of getaddrinfo and// getnameinfo.inline asio::error_code translate_netdb_error(int error){  switch (error)  {  case 0:    return asio::error_code();  case HOST_NOT_FOUND:    return asio::error::host_not_found;  case TRY_AGAIN:    return asio::error::host_not_found_try_again;  case NO_RECOVERY:    return asio::error::no_recovery;  case NO_DATA:    return asio::error::no_data;  default:    BOOST_ASSERT(false);    return asio::error::invalid_argument;  }}inline hostent* gethostbyaddr(const char* addr, int length, int af,    hostent* result, char* buffer, int buflength, asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)  (void)(buffer);  (void)(buflength);  hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);  if (!retval)    return 0;# if defined(UNDER_CE)  clear_error(ec);# endif  *result = *retval;  return retval;#elif defined(__sun) || defined(__QNX__)  int error = 0;  hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result,        buffer, buflength, &error), ec);  if (error)    ec = translate_netdb_error(error);  return retval;#elif defined(__MACH__) && defined(__APPLE__)  (void)(buffer);  (void)(buflength);  int error = 0;  hostent* retval = error_wrapper(::getipnodebyaddr(        addr, length, af, &error), ec);  if (error)    ec = translate_netdb_error(error);  if (!retval)    return 0;  *result = *retval;  return retval;#else  hostent* retval = 0;  int error = 0;  error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer,        buflength, &retval, &error), ec);  if (error)    ec = translate_netdb_error(error);  return retval;#endif}inline hostent* gethostbyname(const char* name, int af, struct hostent* result,    char* buffer, int buflength, int ai_flags, asio::error_code& ec){  clear_error(ec);#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -