src/Network/Address.hh
changeset 382 190f81d30624
parent 381 9b35bc329d23
child 383 2a57f0a871b0
equal deleted inserted replaced
381:9b35bc329d23 382:190f81d30624
     1 #ifndef NETWORK_ADDRESS_HH
     1 #ifndef NETWORK_ADDRESS_H
     2 #define NETWORK_ADDRESS_HH
     2 #define NETWORK_ADDRESS_H
     3 
     3 
     4 #include "../Error.hh"
     4 #include "Endpoint.hh"
     5 
     5 
     6 /*
     6 /*
     7  * Platform-specific includes
     7  * Platform-specific includes
     8  */
     8  */
     9 #ifndef WIN32
     9 #ifndef WIN32
    10     // linux
    10     // linux
    11     #include <sys/types.h>
    11     #include <netinet/in.h>
    12     #include <netdb.h>
       
    13 #else
    12 #else
    14     #error "This network code won't compile on win32 :)"
    13     #error "This network code won't compile on win32 :)"
    15 #endif
    14 #endif
    16 
    15 
    17 #include <string>
       
    18 
       
    19 // assume...
       
    20 #if INET6_ADDRSTRLEN < INET_ADDRSTRLEN
       
    21     #error INET6_ADDRSTRLEN is smaller than INET_ADDRSTRLEN
       
    22 #endif
       
    23 
       
    24 /**
    16 /**
    25  * Length of a network address
    17  * This represents a `struct sockaddr` as used by the socket API.
       
    18  *
       
    19  * It can be used like a NetworkEndpoint, but it's also suitable for use with recvfrom/sendto
    26  */
    20  */
    27 const socklen_t NETWORK_ADDRESS_LENGTH = INET6_ADDRSTRLEN;
    21 class NetworkAddress : public NetworkEndpoint {
    28 
       
    29 /**
       
    30  * We use ClanLib's IPAddress API, but with our own name
       
    31  */ 
       
    32 class NetworkEndpoint {
       
    33     protected:
    22     protected:
    34         /**
    23         /**
    35          * Our human-readable hostname
    24          * The machine-readable address
    36          */
    25          */
    37         std::string hostname;
    26         sockaddr_storage address;
    38 
    27 
    39         /**
    28         /**
    40          * Our human-readable service
    29          * The address length
    41          */
    30          */
    42         std::string service;
    31         socklen_t address_length;
    43 
    32 
    44     public:
    33     public:
    45         /**
    34         /**
    46          * Construct an empty NetworkEndpoint
    35          * Construct an empty SockAddr for later update()
    47          */
    36          */
    48         NetworkEndpoint (void);
    37         NetworkAddress (void);
    49 
    38 
    50         /**
    39         /**
    51          * Construct a NetworkEndpoint with a NULL hostname, and a specific service
    40          * Construct a NetworkAddress from a machine-readable address of the given length
    52          */
    41          */
    53         explicit NetworkEndpoint (std::string service);
    42         NetworkAddress (const sockaddr *addr, socklen_t len);
    54 
    43 
    55         /**
    44         /**
    56          * Construct a NetworkEndpoint on a specific hostname and service
    45          * Get a const sockaddr* in this address
       
    46          *
       
    47          * @return read-only sockaddr pointer
    57          */
    48          */
    58         NetworkEndpoint (std::string hostname, std::string service);
    49         const sockaddr* get_sockaddr (void) const { return (const sockaddr *) &address; }
       
    50 
       
    51         /**
       
    52          * Get a mutable sockaddr* in this address
       
    53          *
       
    54          * @return writeable sockaddr pointer
       
    55          */
       
    56         sockaddr* get_sockaddr (void) { return (sockaddr *) &address; }
       
    57 
       
    58         /**
       
    59          * Get the current address length
       
    60          *
       
    61          * @return address length
       
    62          */
       
    63         socklen_t get_socklen (void) const { return address_length; }
       
    64 
       
    65         /**
       
    66          * Get a the address length pointer, initialized to the size of our sockaddr_storage.
       
    67          *
       
    68          * @return address length pointer
       
    69          */
       
    70         socklen_t* get_socklen_ptr (void) { address_length = sizeof(address); return &address_length; }
       
    71 
       
    72         /**
       
    73          * Copy given sockaddr/len + update
       
    74          */
       
    75         void set_sockaddr (const sockaddr *addr, socklen_t len);
       
    76 
       
    77         /**
       
    78          * Update internal state for NetworkAddress after sockaddr/socklen_ptr have been modified.
       
    79          */
       
    80         void update (void);
    59         
    81         
    60         /*
       
    61          * We can use the default copy-constructor and assignment operator
       
    62          */
       
    63    
       
    64     public:    
       
    65         /**
    82         /**
    66          * Get a addrinfo* for this address using the given family/type/protocol/flags.
    83          * Returns a "fake" addrinfo
    67          *
       
    68          * Remember to free the returned pointer using freeaddrinfo() after use.
       
    69          *
       
    70          * @param family the socket family for hints.ai_family
       
    71          * @param socktype the socket type for hints.ai_socktype
       
    72          * @param protoocl the socket protocol for hints.ai_protocol
       
    73          * @param flags the flags for hints.ai_flags
       
    74          * @return linked list of addrinfo's
       
    75          * @throw NetworkAddressError if resolving this address fails
       
    76          */
    84          */
    77         virtual addrinfo* get_addrinfo (int family, int socktype, int protocol = 0, int flags = 0) const;
    85         virtual addrinfo* get_addrinfo (int family, int socktype, int protocol = 0, int flags = 0) const;
    78         
    86 
    79         /**
    87         /**
    80          * Free an addrinfo returned by get_addrinfo
    88          * Free an addrinfo returned by get_addrinfo
    81          */
    89          */
    82         virtual void free_addrinfo (addrinfo *info) const;
    90         virtual void free_addrinfo (addrinfo *info) const;
    83 
    91 
    84         /**
    92         /**
    85          * Get the human-readable hostname
    93          * Equal-to comparison operator. Invalid addresses compare equal and are always smaller
    86          */
    94          */
    87         virtual std::string get_hostname (void) const { return hostname; }
    95         bool operator== (const NetworkAddress &other) const {
       
    96             return (address_length == other.address_length) && memcmp(&address, &other.address, address_length) == 0;
       
    97         }
    88 
    98 
    89         /**
    99         /**
    90          * Get the human-readable service name
   100          * Not-equal-to comparison operator. Invalid addresses compare equal and are always smaller
    91          */
   101          */
    92         virtual std::string get_service (void) const { return service; }
   102         bool operator!= (const NetworkAddress &other) const {
       
   103             return (address_length != other.address_length) || memcmp(&address, &other.address, address_length) != 0;
       
   104         }
       
   105 
       
   106         /**
       
   107          * Less-than comparison operator. Smaller addresses are always lesser.
       
   108          */
       
   109         bool operator< (const NetworkAddress &other) const {
       
   110             return (address_length < other.address_length) || memcmp(&address, &other.address, other.address_length) < 0;
       
   111         }
       
   112 
       
   113         /**
       
   114          * Greater-than comparison operator. Bigger addresses are always greater.
       
   115          */
       
   116         bool operator> (const NetworkAddress &other) const {
       
   117             return (address_length > other.address_length) || memcmp(&address, &other.address, address_length) > 0;
       
   118         }
    93 };
   119 };
    94 
   120 
    95 /**
   121 #endif
    96  * Formatted as  [<addr>:<port>]
       
    97  */
       
    98 std::ostream& operator<< (std::ostream &s, const NetworkEndpoint &addr);
       
    99 
       
   100 /**
       
   101  *
       
   102  */
       
   103 class NetworkAddressError : public Error {
       
   104     protected:
       
   105         static std::string build_str (const NetworkEndpoint &addr, const char *op, const char *msg);
       
   106 
       
   107     public:
       
   108         NetworkAddressError (const NetworkEndpoint &addr, const char *op, const char *msg);
       
   109 };
       
   110 
       
   111 #endif /* NETWORK_ADDRESS_HH */