src/Network/SockAddr.cc
author terom
Wed, 17 Dec 2008 00:40:22 +0000
changeset 381 9b35bc329d23
permissions -rw-r--r--
separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint

#include "SockAddr.hh"

#include <cstdlib>

NetworkAddress::NetworkAddress (void) :
    NetworkEndpoint(), address_length(0)
{

}

NetworkAddress::NetworkAddress (const sockaddr *addr, socklen_t len) :
    NetworkEndpoint(), address_length(0)
{
    // proxy to set_sockaddr
    set_sockaddr(addr, len);
}
 
void NetworkAddress::set_sockaddr (const sockaddr *addr, socklen_t len) {
    // invalid length?
    if (len <= 0 || len > sizeof(address))
        throw NetworkAddressError(*this, "set_sockaddr", "invalid sockaddr length");

    // copy over to address
    memcpy(&address, addr, len);
    
    // set address_length
    address_length = len;
    
   // update
   update();
}

void NetworkAddress::update (void) {
    char host_buf[NI_MAXHOST], serv_buf[NI_MAXSERV];
    int err;

    // do getnameinfo()
    if ((err = getnameinfo((sockaddr *) &address, address_length, host_buf, NI_MAXHOST, serv_buf, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV)))
        throw NetworkAddressError(*this, "getnameinfo", gai_strerror(err));
    
    // update hostname + service
    hostname = host_buf;
    service = serv_buf;
}

addrinfo* NetworkAddress::get_addrinfo (int family, int socktype, int protocol, int flags) const {
    (void) flags;

    // get my family from address
    int my_family = address.ss_family;
    
    // right family?
    if (family && family != my_family)
        throw NetworkAddressError(*this, "fake_getaddrinfo", "ai_family mismatch");
    
    // alllocate new addrinfo
    addrinfo *r = new addrinfo;

    // set it up
    r->ai_flags = 0;
    r->ai_family = my_family;
    r->ai_socktype = socktype;
    r->ai_protocol = protocol;
    r->ai_addrlen = get_socklen();
    r->ai_addr = const_cast<sockaddr *>(get_sockaddr());
    r->ai_canonname = const_cast<char *>(get_hostname().c_str());
    r->ai_next = NULL;

    // return it
    return r;
}

void NetworkAddress::free_addrinfo (addrinfo *info) const {
    delete info;
}