src/Network/Address.cc
changeset 378 5589abf5e61b
parent 187 f41f894213ca
child 379 2a8e780844d2
equal deleted inserted replaced
377:01d3c340b372 378:5589abf5e61b
     1 
     1 
     2 #include "Address.hh"
     2 #include "Address.hh"
     3 
     3 
     4 #include <sstream>
     4 #include <sstream>
     5 
     5 
       
     6 NetworkAddress::NetworkAddress (void) :
       
     7     hostname(), service(), address_length(0)
       
     8 {
       
     9 
       
    10 }
       
    11 
       
    12 NetworkAddress::NetworkAddress (std::string service) :
       
    13     hostname(), service(service), address_length(0)
       
    14 {
       
    15 
       
    16 }
       
    17         
       
    18 NetworkAddress::NetworkAddress (std::string hostname, std::string service) :
       
    19     hostname(hostname), service(service), address_length(0)
       
    20 {
       
    21 
       
    22 }
       
    23         
       
    24 NetworkAddress::NetworkAddress (const sockaddr *addr, socklen_t len) :
       
    25     hostname(hostname), service(service), address_length(0)
       
    26 {
       
    27     // proxy to set_sockaddr
       
    28     set_sockaddr(addr, len);
       
    29 }
       
    30         
       
    31 addrinfo* NetworkAddress::get_addrinfo (int family, int socktype, int protocol, int flags) const {
       
    32     addrinfo hints, *results;
       
    33     int err;
       
    34     
       
    35     // initialize flags
       
    36     hints.ai_flags = flags;
       
    37     hints.ai_family = family;
       
    38     hints.ai_socktype = socktype;
       
    39     hints.ai_protocol = protocol;
       
    40     hints.ai_addrlen = 0;
       
    41     hints.ai_canonname = NULL;
       
    42     hints.ai_next = NULL;
       
    43 
       
    44     // hostname + service may be NULL
       
    45     const char *hostname = this->hostname.empty() ? NULL : this->hostname.c_str();
       
    46     const char *service = this->service.empty() ? NULL : this->service.c_str();
       
    47 
       
    48     // do getaddrinfo()
       
    49     if ((err = getaddrinfo(hostname, service, &hints, &results)))
       
    50         throw NetworkAddressError(*this, "getaddrinfo", gai_strerror(err));
       
    51 
       
    52     // done
       
    53     return results;
       
    54 }
       
    55         
       
    56 const sockaddr* NetworkAddress::get_sockaddr (socklen_t &len_ref) const {
       
    57     // we can't figure this out ourselves...
       
    58     if (address_length == 0)
       
    59         throw Error("NetworkAddress::get_sockaddr called without a valid sockaddr set");
       
    60     
       
    61     // update len
       
    62     len_ref = address_length;
       
    63     
       
    64     // and return a pointer to our internal address
       
    65     return (const sockaddr*) &address;
       
    66 }
       
    67 
       
    68 void NetworkAddress::set_sockaddr (const sockaddr *addr, socklen_t len) {
       
    69     char host_buf[NI_MAXHOST], serv_buf[NI_MAXSERV];
       
    70     int err;
       
    71 
       
    72     // invalid length?
       
    73     if (len > sizeof(this->address))
       
    74         throw NetworkAddressError(*this, "set_sockaddr", "invalid sockaddr length");
       
    75 
       
    76     // do getnameinfo()
       
    77     if ((err = getnameinfo(addr, len, host_buf, NI_MAXHOST, serv_buf, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV)))
       
    78         throw NetworkAddressError(*this, "getnameinfo", gai_strerror(err));
       
    79     
       
    80     // copy over to address
       
    81     memcpy(&this->address, addr, len);
       
    82 }
       
    83 
     6 std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr) {
    84 std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr) {
     7     s << "[" << addr.get_address() << ":" << addr.get_port() << "]";
    85     s << "[" << addr.get_hostname() << ":" << addr.get_service() << "]";
     8 
    86 
     9     return s;
    87     return s;
    10 
    88 
    11 }
    89 }
    12  
    90  
       
    91 std::string NetworkAddressError::build_str (const NetworkAddress &addr, const char *op, const char *msg) {
       
    92     std::stringstream ss;
       
    93 
       
    94     ss << op << ": " << addr << ": " << msg;
       
    95 
       
    96     return ss.str();
       
    97 }
       
    98 
       
    99 NetworkAddressError::NetworkAddressError (const NetworkAddress &addr, const char *op, const char *msg) :
       
   100     Error(build_str(addr, op, msg))
       
   101 {
       
   102 
       
   103 }
       
   104 
       
   105 
       
   106