src/Network/Endpoint.hh
author Tero Marttila <terom@fixme.fi>
Fri, 16 Jan 2009 22:03:49 +0200
changeset 400 d64bf28c4340
parent 399 c7295b72731a
permissions -rw-r--r--
more documentation tweaking, all Network/ files now have a @file comment. Fix Platform.h -> Platform.hh, and Buffer.hh + Packet.cc
#ifndef NETWORK_ENDPOINT_HH
#define NETWORK_ENDPOINT_HH

/**
 * @file
 *
 * Textual NetworkEndpoint addresses
 */

#include "../Error.hh"
#include "Platform.hh"

#include <string>

// assume...
#if INET6_ADDRSTRLEN < INET_ADDRSTRLEN
    #error INET6_ADDRSTRLEN is smaller than INET_ADDRSTRLEN
#endif

/**
 * Length of a network address in text form
 */
const socklen_t NETWORK_ADDRESS_LENGTH = INET6_ADDRSTRLEN;

/**
 * NetworkEndpoint is mostly used to pass addresses from the (human) user to NetworkSocket's bind()/connect(). The 
 * constructor accepts a textual service name (port) and hostname (literal IP adddress or hostname), and can then
 * provide a list of resolved addresses for use by NetworkSocket (using the libc getaddrinfo). Additionally,
 * methods/operators are defined for textual output of the address.
 *
 * It may be of value to note that the hostname/service is only interpreted by the get_addrinfo() method, which means
 * that invalid/non-existant hostnames/services will only raise an error once the NetworkEndpoint is passed to
 * NetworkSocket.
 *
 * All DNS lookups are blocking.
 */ 
class NetworkEndpoint {
    protected:
        /**
         * Our human-readable hostname
         */
        std::string hostname;

        /**
         * Our human-readable service
         */
        std::string service;

    public:
        /**
         * Construct an empty NetworkEndpoint
         */
        NetworkEndpoint (void);

        /**
         * Construct a NetworkEndpoint with a NULL hostname, and a specific service
         */
        explicit NetworkEndpoint (std::string service);

        /**
         * Construct a NetworkEndpoint on a specific hostname and service
         */
        NetworkEndpoint (std::string hostname, std::string service);
        
        /*
         * We can use the default copy-constructor and assignment operator
         */
   
    public:    
        /**
         * Get a addrinfo* for this address using the given family/type/protocol/flags.
         *
         * Remember to free the returned pointer using freeaddrinfo() after use.
         *
         * @param family the socket family for hints.ai_family
         * @param socktype the socket type for hints.ai_socktype
         * @param protoocl the socket protocol for hints.ai_protocol
         * @param flags the flags for hints.ai_flags
         * @return linked list of addrinfo's
         * @throw NetworkAddressError if resolving this address fails
         */
        virtual addrinfo* get_addrinfo (int family, int socktype, int protocol = 0, int flags = 0) const;
        
        /**
         * Free an addrinfo returned by get_addrinfo
         */
        virtual void free_addrinfo (addrinfo *info) const;

        /**
         * Get the human-readable hostname
         */
        virtual std::string get_hostname (void) const { return hostname; }

        /**
         * Get the human-readable service name
         */
        virtual std::string get_service (void) const { return service; }
};

/**
 * Formatted as  [<addr>:<port>]
 */
std::ostream& operator<< (std::ostream &s, const NetworkEndpoint &addr);

/**
 * Errors raised by NetworkEndpoint, so e.g. DNS errors (hostname not found etc.)
 */
class NetworkAddressError : public Error {
    protected:
        static std::string build_str (const NetworkEndpoint &addr, const char *op, const char *msg);

    public:
        NetworkAddressError (const NetworkEndpoint &addr, const char *op, const char *msg);
};

#endif /* NETWORK_ADDRESS_HH */