Home | History | Annotate | Download | only in impl
      1 //
      2 // ip/detail/impl/endpoint.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_IP_DETAIL_IMPL_ENDPOINT_IPP
     12 #define ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP
     13 
     14 
     15 #include "asio/detail/config.hpp"
     16 #include <cstring>
     17 #include "asio/detail/socket_ops.hpp"
     18 #include "asio/detail/throw_error.hpp"
     19 #include "asio/error.hpp"
     20 #include "asio/ip/detail/endpoint.hpp"
     21 
     22 #include "asio/detail/push_options.hpp"
     23 
     24 namespace asio {
     25 namespace ip {
     26 namespace detail {
     27 
     28 endpoint::endpoint()
     29   : data_()
     30 {
     31   data_.v4.sin_family = ASIO_OS_DEF(AF_INET);
     32   data_.v4.sin_port = 0;
     33   data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY);
     34 }
     35 
     36 endpoint::endpoint(int family, unsigned short port_num)
     37   : data_()
     38 {
     39   using namespace std; // For memcpy.
     40   if (family == ASIO_OS_DEF(AF_INET))
     41   {
     42     data_.v4.sin_family = ASIO_OS_DEF(AF_INET);
     43     data_.v4.sin_port =
     44       asio::detail::socket_ops::host_to_network_short(port_num);
     45     data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY);
     46   }
     47   else
     48   {
     49     data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6);
     50     data_.v6.sin6_port =
     51       asio::detail::socket_ops::host_to_network_short(port_num);
     52     data_.v6.sin6_flowinfo = 0;
     53     data_.v6.sin6_addr.s6_addr[0] = 0; data_.v6.sin6_addr.s6_addr[1] = 0;
     54     data_.v6.sin6_addr.s6_addr[2] = 0, data_.v6.sin6_addr.s6_addr[3] = 0;
     55     data_.v6.sin6_addr.s6_addr[4] = 0, data_.v6.sin6_addr.s6_addr[5] = 0;
     56     data_.v6.sin6_addr.s6_addr[6] = 0, data_.v6.sin6_addr.s6_addr[7] = 0;
     57     data_.v6.sin6_addr.s6_addr[8] = 0, data_.v6.sin6_addr.s6_addr[9] = 0;
     58     data_.v6.sin6_addr.s6_addr[10] = 0, data_.v6.sin6_addr.s6_addr[11] = 0;
     59     data_.v6.sin6_addr.s6_addr[12] = 0, data_.v6.sin6_addr.s6_addr[13] = 0;
     60     data_.v6.sin6_addr.s6_addr[14] = 0, data_.v6.sin6_addr.s6_addr[15] = 0;
     61     data_.v6.sin6_scope_id = 0;
     62   }
     63 }
     64 
     65 endpoint::endpoint(const asio::ip::address& addr,
     66     unsigned short port_num)
     67   : data_()
     68 {
     69   using namespace std; // For memcpy.
     70   if (addr.is_v4())
     71   {
     72     data_.v4.sin_family = ASIO_OS_DEF(AF_INET);
     73     data_.v4.sin_port =
     74       asio::detail::socket_ops::host_to_network_short(port_num);
     75     data_.v4.sin_addr.s_addr =
     76       asio::detail::socket_ops::host_to_network_long(
     77           static_cast<asio::detail::u_long_type>(
     78             addr.to_v4().to_ulong()));
     79   }
     80   else
     81   {
     82     data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6);
     83     data_.v6.sin6_port =
     84       asio::detail::socket_ops::host_to_network_short(port_num);
     85     data_.v6.sin6_flowinfo = 0;
     86     asio::ip::address_v6 v6_addr = addr.to_v6();
     87     asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes();
     88     memcpy(data_.v6.sin6_addr.s6_addr, bytes.data(), 16);
     89     data_.v6.sin6_scope_id =
     90       static_cast<asio::detail::u_long_type>(
     91         v6_addr.scope_id());
     92   }
     93 }
     94 
     95 void endpoint::resize(std::size_t new_size)
     96 {
     97   if (new_size > sizeof(asio::detail::sockaddr_storage_type))
     98   {
     99     asio::error_code ec(asio::error::invalid_argument);
    100     asio::detail::throw_error(ec);
    101   }
    102 }
    103 
    104 unsigned short endpoint::port() const
    105 {
    106   if (is_v4())
    107   {
    108     return asio::detail::socket_ops::network_to_host_short(
    109         data_.v4.sin_port);
    110   }
    111   else
    112   {
    113     return asio::detail::socket_ops::network_to_host_short(
    114         data_.v6.sin6_port);
    115   }
    116 }
    117 
    118 void endpoint::port(unsigned short port_num)
    119 {
    120   if (is_v4())
    121   {
    122     data_.v4.sin_port
    123       = asio::detail::socket_ops::host_to_network_short(port_num);
    124   }
    125   else
    126   {
    127     data_.v6.sin6_port
    128       = asio::detail::socket_ops::host_to_network_short(port_num);
    129   }
    130 }
    131 
    132 asio::ip::address endpoint::address() const
    133 {
    134   using namespace std; // For memcpy.
    135   if (is_v4())
    136   {
    137     return asio::ip::address_v4(
    138         asio::detail::socket_ops::network_to_host_long(
    139           data_.v4.sin_addr.s_addr));
    140   }
    141   else
    142   {
    143     asio::ip::address_v6::bytes_type bytes;
    144     memcpy(bytes.data(), data_.v6.sin6_addr.s6_addr, 16);
    145     return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id);
    146   }
    147 }
    148 
    149 void endpoint::address(const asio::ip::address& addr)
    150 {
    151   endpoint tmp_endpoint(addr, port());
    152   data_ = tmp_endpoint.data_;
    153 }
    154 
    155 bool operator==(const endpoint& e1, const endpoint& e2)
    156 {
    157   return e1.address() == e2.address() && e1.port() == e2.port();
    158 }
    159 
    160 bool operator<(const endpoint& e1, const endpoint& e2)
    161 {
    162   if (e1.address() < e2.address())
    163     return true;
    164   if (e1.address() != e2.address())
    165     return false;
    166   return e1.port() < e2.port();
    167 }
    168 
    169 
    170 } // namespace detail
    171 } // namespace ip
    172 } // namespace asio
    173 
    174 #include "asio/detail/pop_options.hpp"
    175 
    176 #endif // ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP
    177