src/Network/Address.cc
changeset 378 5589abf5e61b
parent 187 f41f894213ca
child 379 2a8e780844d2
--- a/src/Network/Address.cc	Mon Dec 15 16:41:00 2008 +0000
+++ b/src/Network/Address.cc	Mon Dec 15 23:56:42 2008 +0000
@@ -3,10 +3,104 @@
 
 #include <sstream>
 
+NetworkAddress::NetworkAddress (void) :
+    hostname(), service(), address_length(0)
+{
+
+}
+
+NetworkAddress::NetworkAddress (std::string service) :
+    hostname(), service(service), address_length(0)
+{
+
+}
+        
+NetworkAddress::NetworkAddress (std::string hostname, std::string service) :
+    hostname(hostname), service(service), address_length(0)
+{
+
+}
+        
+NetworkAddress::NetworkAddress (const sockaddr *addr, socklen_t len) :
+    hostname(hostname), service(service), address_length(0)
+{
+    // proxy to set_sockaddr
+    set_sockaddr(addr, len);
+}
+        
+addrinfo* NetworkAddress::get_addrinfo (int family, int socktype, int protocol, int flags) const {
+    addrinfo hints, *results;
+    int err;
+    
+    // initialize flags
+    hints.ai_flags = flags;
+    hints.ai_family = family;
+    hints.ai_socktype = socktype;
+    hints.ai_protocol = protocol;
+    hints.ai_addrlen = 0;
+    hints.ai_canonname = NULL;
+    hints.ai_next = NULL;
+
+    // hostname + service may be NULL
+    const char *hostname = this->hostname.empty() ? NULL : this->hostname.c_str();
+    const char *service = this->service.empty() ? NULL : this->service.c_str();
+
+    // do getaddrinfo()
+    if ((err = getaddrinfo(hostname, service, &hints, &results)))
+        throw NetworkAddressError(*this, "getaddrinfo", gai_strerror(err));
+
+    // done
+    return results;
+}
+        
+const sockaddr* NetworkAddress::get_sockaddr (socklen_t &len_ref) const {
+    // we can't figure this out ourselves...
+    if (address_length == 0)
+        throw Error("NetworkAddress::get_sockaddr called without a valid sockaddr set");
+    
+    // update len
+    len_ref = address_length;
+    
+    // and return a pointer to our internal address
+    return (const sockaddr*) &address;
+}
+
+void NetworkAddress::set_sockaddr (const sockaddr *addr, socklen_t len) {
+    char host_buf[NI_MAXHOST], serv_buf[NI_MAXSERV];
+    int err;
+
+    // invalid length?
+    if (len > sizeof(this->address))
+        throw NetworkAddressError(*this, "set_sockaddr", "invalid sockaddr length");
+
+    // do getnameinfo()
+    if ((err = getnameinfo(addr, len, host_buf, NI_MAXHOST, serv_buf, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV)))
+        throw NetworkAddressError(*this, "getnameinfo", gai_strerror(err));
+    
+    // copy over to address
+    memcpy(&this->address, addr, len);
+}
+
 std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr) {
-    s << "[" << addr.get_address() << ":" << addr.get_port() << "]";
+    s << "[" << addr.get_hostname() << ":" << addr.get_service() << "]";
 
     return s;
 
 }
  
+std::string NetworkAddressError::build_str (const NetworkAddress &addr, const char *op, const char *msg) {
+    std::stringstream ss;
+
+    ss << op << ": " << addr << ": " << msg;
+
+    return ss.str();
+}
+
+NetworkAddressError::NetworkAddressError (const NetworkAddress &addr, const char *op, const char *msg) :
+    Error(build_str(addr, op, msg))
+{
+
+}
+
+
+