terom@381: #ifndef NETWORK_SOCKADDR_H terom@381: #define NETWORK_SOCKADDR_H terom@381: terom@381: #include "Address.hh" terom@381: terom@381: /* terom@381: * Platform-specific includes terom@381: */ terom@381: #ifndef WIN32 terom@381: // linux terom@381: #include terom@381: #else terom@381: #error "This network code won't compile on win32 :)" terom@381: #endif terom@381: terom@381: terom@381: /** terom@381: * This represents a `struct sockaddr` as used by the socket API. terom@381: * terom@381: * It can be used like a NetworkEndpoint, but it's also suitable for use with recvfrom/sendto terom@381: */ terom@381: class NetworkAddress : public NetworkEndpoint { terom@381: protected: terom@381: /** terom@381: * The machine-readable address terom@381: */ terom@381: sockaddr_storage address; terom@381: terom@381: /** terom@381: * The address length terom@381: */ terom@381: socklen_t address_length; terom@381: terom@381: public: terom@381: /** terom@381: * Construct an empty SockAddr for later update() terom@381: */ terom@381: NetworkAddress (void); terom@381: terom@381: /** terom@381: * Construct a NetworkAddress from a machine-readable address of the given length terom@381: */ terom@381: NetworkAddress (const sockaddr *addr, socklen_t len); terom@381: terom@381: /** terom@381: * Get a const sockaddr* in this address terom@381: * terom@381: * @return read-only sockaddr pointer terom@381: */ terom@381: const sockaddr* get_sockaddr (void) const { return (const sockaddr *) &address; } terom@381: terom@381: /** terom@381: * Get a mutable sockaddr* in this address terom@381: * terom@381: * @return writeable sockaddr pointer terom@381: */ terom@381: sockaddr* get_sockaddr (void) { return (sockaddr *) &address; } terom@381: terom@381: /** terom@381: * Get the current address length terom@381: * terom@381: * @return address length terom@381: */ terom@381: socklen_t get_socklen (void) const { return address_length; } terom@381: terom@381: /** terom@381: * Get a the address length pointer, initialized to the size of our sockaddr_storage. terom@381: * terom@381: * @return address length pointer terom@381: */ terom@381: socklen_t* get_socklen_ptr (void) { address_length = sizeof(address); return &address_length; } terom@381: terom@381: /** terom@381: * Copy given sockaddr/len + update terom@381: */ terom@381: void set_sockaddr (const sockaddr *addr, socklen_t len); terom@381: terom@381: /** terom@381: * Update internal state for NetworkAddress after sockaddr/socklen_ptr have been modified. terom@381: */ terom@381: void update (void); terom@381: terom@381: /** terom@381: * Returns a "fake" addrinfo terom@381: */ terom@381: virtual addrinfo* get_addrinfo (int family, int socktype, int protocol = 0, int flags = 0) const; terom@381: terom@381: /** terom@381: * Free an addrinfo returned by get_addrinfo terom@381: */ terom@381: virtual void free_addrinfo (addrinfo *info) const; terom@381: terom@381: /** terom@381: * Equal-to comparison operator. Invalid addresses compare equal and are always smaller terom@381: */ terom@381: bool operator== (const NetworkAddress &other) const { terom@381: return (address_length == other.address_length) && memcmp(&address, &other.address, address_length) == 0; terom@381: } terom@381: terom@381: /** terom@381: * Not-equal-to comparison operator. Invalid addresses compare equal and are always smaller terom@381: */ terom@381: bool operator!= (const NetworkAddress &other) const { terom@381: return (address_length != other.address_length) || memcmp(&address, &other.address, address_length) != 0; terom@381: } terom@381: terom@381: /** terom@381: * Less-than comparison operator. Smaller addresses are always lesser. terom@381: */ terom@381: bool operator< (const NetworkAddress &other) const { terom@381: return (address_length < other.address_length) || memcmp(&address, &other.address, other.address_length) < 0; terom@381: } terom@381: terom@381: /** terom@381: * Greater-than comparison operator. Bigger addresses are always greater. terom@381: */ terom@381: bool operator> (const NetworkAddress &other) const { terom@381: return (address_length > other.address_length) || memcmp(&address, &other.address, address_length) > 0; terom@381: } terom@381: }; terom@381: terom@381: #endif