Home | History | Annotate | Download | only in common
      1 //===-- SocketAddress.cpp ---------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/Host/SocketAddress.h"
     11 #include <stddef.h>
     12 
     13 // C Includes
     14 #include <assert.h>
     15 #include <string.h>
     16 
     17 // C++ Includes
     18 // Other libraries and framework includes
     19 // Project includes
     20 
     21 using namespace lldb_private;
     22 
     23 //----------------------------------------------------------------------
     24 // SocketAddress constructor
     25 //----------------------------------------------------------------------
     26 SocketAddress::SocketAddress ()
     27 {
     28     Clear ();
     29 }
     30 
     31 SocketAddress::SocketAddress (const struct sockaddr &s)
     32 {
     33     m_socket_addr.sa = s;
     34 }
     35 
     36 
     37 SocketAddress::SocketAddress (const struct sockaddr_in &s)
     38 {
     39     m_socket_addr.sa_ipv4 = s;
     40 }
     41 
     42 
     43 SocketAddress::SocketAddress (const struct sockaddr_in6 &s)
     44 {
     45     m_socket_addr.sa_ipv6 = s;
     46 }
     47 
     48 
     49 SocketAddress::SocketAddress (const struct sockaddr_storage &s)
     50 {
     51     m_socket_addr.sa_storage = s;
     52 }
     53 
     54 //----------------------------------------------------------------------
     55 // SocketAddress copy constructor
     56 //----------------------------------------------------------------------
     57 SocketAddress::SocketAddress (const SocketAddress& rhs) :
     58     m_socket_addr (rhs.m_socket_addr)
     59 {
     60 }
     61 
     62 //----------------------------------------------------------------------
     63 // Destructor
     64 //----------------------------------------------------------------------
     65 SocketAddress::~SocketAddress()
     66 {
     67 }
     68 
     69 void
     70 SocketAddress::Clear ()
     71 {
     72     memset (&m_socket_addr, 0, sizeof(m_socket_addr));
     73 }
     74 
     75 bool
     76 SocketAddress::IsValid () const
     77 {
     78     return GetLength () != 0;
     79 }
     80 
     81 static socklen_t
     82 GetFamilyLength (sa_family_t family)
     83 {
     84     switch (family)
     85     {
     86         case AF_INET:  return sizeof(struct sockaddr_in);
     87         case AF_INET6: return sizeof(struct sockaddr_in6);
     88     }
     89     assert(0 && "Unsupported address family");
     90 }
     91 
     92 socklen_t
     93 SocketAddress::GetLength () const
     94 {
     95 #if defined(__APPLE__)
     96     return m_socket_addr.sa.sa_len;
     97 #else
     98     return GetFamilyLength (GetFamily());
     99 #endif
    100 }
    101 
    102 socklen_t
    103 SocketAddress::GetMaxLength ()
    104 {
    105     return sizeof (sockaddr_t);
    106 }
    107 
    108 sa_family_t
    109 SocketAddress::GetFamily () const
    110 {
    111     return m_socket_addr.sa.sa_family;
    112 }
    113 
    114 void
    115 SocketAddress::SetFamily (sa_family_t family)
    116 {
    117     m_socket_addr.sa.sa_family = family;
    118 #if defined(__APPLE__)
    119     m_socket_addr.sa.sa_len = GetFamilyLength (family);
    120 #endif
    121 }
    122 
    123 in_port_t
    124 SocketAddress::GetPort () const
    125 {
    126     switch (GetFamily())
    127     {
    128         case AF_INET:   return m_socket_addr.sa_ipv4.sin_port;
    129         case AF_INET6:  return m_socket_addr.sa_ipv6.sin6_port;
    130     }
    131     return 0;
    132 }
    133 
    134 bool
    135 SocketAddress::SetPort (in_port_t port)
    136 {
    137     switch (GetFamily())
    138     {
    139         case AF_INET:
    140             m_socket_addr.sa_ipv4.sin_port = htons(port);
    141             return true;
    142 
    143         case AF_INET6:
    144             m_socket_addr.sa_ipv6.sin6_port = htons(port);
    145             return true;
    146     }
    147     return false;
    148 }
    149 
    150 //----------------------------------------------------------------------
    151 // SocketAddress assignment operator
    152 //----------------------------------------------------------------------
    153 const SocketAddress&
    154 SocketAddress::operator=(const SocketAddress& rhs)
    155 {
    156     if (this != &rhs)
    157         m_socket_addr = rhs.m_socket_addr;
    158     return *this;
    159 }
    160 
    161 const SocketAddress&
    162 SocketAddress::operator=(const struct addrinfo *addr_info)
    163 {
    164     Clear();
    165     if (addr_info &&
    166         addr_info->ai_addr &&
    167         addr_info->ai_addrlen > 0&&
    168         addr_info->ai_addrlen <= sizeof m_socket_addr)
    169     {
    170         ::memcpy (&m_socket_addr,
    171                   addr_info->ai_addr,
    172                   addr_info->ai_addrlen);
    173     }
    174     return *this;
    175 }
    176 
    177 const SocketAddress&
    178 SocketAddress::operator=(const struct sockaddr &s)
    179 {
    180     m_socket_addr.sa = s;
    181     return *this;
    182 }
    183 
    184 const SocketAddress&
    185 SocketAddress::operator=(const struct sockaddr_in &s)
    186 {
    187     m_socket_addr.sa_ipv4 = s;
    188     return *this;
    189 }
    190 
    191 const SocketAddress&
    192 SocketAddress::operator=(const struct sockaddr_in6 &s)
    193 {
    194     m_socket_addr.sa_ipv6 = s;
    195     return *this;
    196 }
    197 
    198 const SocketAddress&
    199 SocketAddress::operator=(const struct sockaddr_storage &s)
    200 {
    201     m_socket_addr.sa_storage = s;
    202     return *this;
    203 }
    204 
    205 bool
    206 SocketAddress::SetAddress (const struct addrinfo *hints_ptr,
    207                            const char *host,
    208                            const char *service,
    209                            struct addrinfo *addr_info_ptr)
    210 {
    211     struct addrinfo *service_info_list = NULL;
    212     int err = ::getaddrinfo (host, service, hints_ptr, &service_info_list);
    213     if (err == 0 && service_info_list)
    214     {
    215         if (addr_info_ptr)
    216             *addr_info_ptr = *service_info_list;
    217         *this = service_info_list;
    218     }
    219     else
    220         Clear();
    221 
    222     :: freeaddrinfo (service_info_list);
    223 
    224     const bool is_valid = IsValid();
    225     if (!is_valid)
    226     {
    227         if (addr_info_ptr)
    228             ::memset (addr_info_ptr, 0, sizeof(struct addrinfo));
    229     }
    230     return is_valid;
    231 }
    232 
    233 
    234 bool
    235 SocketAddress::SetToLocalhost (sa_family_t family, in_port_t port)
    236 {
    237     switch (family)
    238     {
    239         case AF_INET:
    240             SetFamily (AF_INET);
    241             if (SetPort (port))
    242             {
    243                 m_socket_addr.sa_ipv4.sin_addr.s_addr = htonl (INADDR_ANY);
    244                 return true;
    245             }
    246             break;
    247 
    248         case AF_INET6:
    249             SetFamily (AF_INET6);
    250             if (SetPort (port))
    251             {
    252                 m_socket_addr.sa_ipv6.sin6_addr = in6addr_any;
    253                 return true;
    254             }
    255             break;
    256 
    257     }
    258     Clear();
    259     return false;
    260 }
    261