X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FProtocols%2FBSDSocketAddress.hh;h=2040513e11bea285fe93c49acbfc0dfa0376c6ad;hb=6927c87144ca23845065e3c23e37c75f5f059cf3;hp=6b2dfe28979d50c6ae9386b2bae7fa5197f7dc92;hpb=1004d55779889e573ab51cf007ea5e25434165a7;p=senf.git diff --git a/Socket/Protocols/BSDSocketAddress.hh b/Socket/Protocols/BSDSocketAddress.hh index 6b2dfe2..2040513 100644 --- a/Socket/Protocols/BSDSocketAddress.hh +++ b/Socket/Protocols/BSDSocketAddress.hh @@ -23,10 +23,13 @@ /** \file \brief BSDSocketAddress public header */ -#ifndef HH_BSDSocketAddress_ -#define HH_BSDSocketAddress_ 1 +#ifndef HH_SENF_Socket_Protocols_BSDSocketAddress_ +#define HH_SENF_Socket_Protocols_BSDSocketAddress_ 1 // Custom includes +#include +#include +#include #include "../../Utils/safe_bool.hh" #include #include @@ -36,21 +39,68 @@ namespace senf { - /** \brief + /** \brief Socket addressing, BSD style + + BSDSocketAddress is the base class of all BSD \c sockaddr based addressing classes. The \c + sockaddr addressing interface is split into several parts + + \li The BSDSocketAddress provides a read-only and generic \c sockaddr interface + \li Address family specific derived classes implement addressing of a specific type. These + are INet4SocketAddress (\c AF_INET), INet6SocketAddress (\c AF_INET6), UNSocketAddress + (\c AF_UNIX) and LLSocketAddress (\c AF_PACKET) + \li GenericBSDSocketAddress provides writable support for generic addresses. + + It is \e not possible to create or store BSDSocketAddress instances: You must either store + an address in one of the specifically typed subclasses or using GenericBSDSocketAddress. + + A BSDSocketAddress or GenericBSDSocketAddress can be cast (like a downcast) to (the correct) + type specific cast using sockaddr_cast: + + \code + void foo(senf::BSDSOcketAddress const & addr) + { + if (addr.family() == senf::INet4SocketAddress::addressFamily) { + senf::INet4SocketAddress i4addr ( + senf::sockaddr_cast(addr) ); + ... + } + } + \endcode + + All these classes provide a generic \c sockaddr API to interface with legacy \c sockaddr + based code (e.g. the BSD socket API). In this base-class, this interface is read-only, the + derived classes however provide a read-write interface. + + \ingroup addr_group */ class BSDSocketAddress - : public senf::comparable_safe_bool + : public senf::comparable_safe_bool, + public boost::less_than_comparable, + public boost::equality_comparable { public: - - bool operator==(BSDSocketAddress const & other) const; - bool operator!=(BSDSocketAddress const & other) const; - - bool boolean_test() const; - short family() const; + bool operator==(BSDSocketAddress const & other) const; ///< Compare two arbitrary addresses + /**< For addresses to be considered equal, they must have + the same family, length and the data must be + identical. */ + bool operator<(BSDSocketAddress const & other) const; ///< Compare two arbitrary addresses + /**< Ordering is based on the in-memory representation. It + is primarily useful to use addresses as keys in a map + or set. */ + + bool boolean_test() const; ///< Return \c true, if address is not empty + /**< An address is considered empty if + \li the family is AF_UNSPEC + \li or the size is 0 + \li or all data bytes are 0 */ + + short family() const; ///< Return the address family. + /**< This value is found in the \c addressFamily member of + each typed derived class + (e.g. INet4Address::addressFamily) */ /////////////////////////////////////////////////////////////////////////// - ///\name Generic \c sockaddr interface + ///\name Generic sockaddr interface ///\{ struct sockaddr const * sockaddr_p() const; @@ -70,19 +120,54 @@ namespace senf { void socklen(socklen_t len); private: - - socklen_t len_; + // The following incantation is needed to fix the alignment of the sockaddr data members + // which will be added by the derived classes later: The alignment must be forced + // to coincide with the struct sockaddr_storage alignment (which must have the largest + // alignment of all sockaddr types). + union { + socklen_t len_; + boost::type_with_alignment::value> a_; + char _b[boost::alignment_of::value]; + }; }; + /** \brief Safe socket address down-cast + + sockaddr_cast allows to safely cast a socket address to it's derived type. Only the family + specific derived addressing classes are permissible for \a Target. + + This cast is especially useful to cast a GenericBSDSocketAddress to it's concrete type. + + \related BSDSocketAddress + */ template Target & sockaddr_cast(BSDSocketAddress & source); + /** \brief Safe socket address down-cast (const) + \see sockaddr_cast() + \related BSDSocketAddress + */ template Target const & sockaddr_cast(BSDSocketAddress const & source); + /** \brief Output generic socket address + + This stream operator will output a generic BSDSocketAddress in a family depending format. + + \related BSDSocketAddress + */ std::ostream & operator<<(std::ostream & os, BSDSocketAddress const & addr); - /** \brief + /** \brief Generic BSD \c sockaddr storage + + While BSDSocketAddress provides read-only generic \c sockaddr access, + GenericBSDSocketAddress allows to store (write) arbitrary socket addresses. (It is + internally based on \c sockaddr_storage). + + To access the stored address, use sockaddr_cast to cast the GenericBSDSocketAddress to the + correct family specific address class. + + \ingroup addr_group */ class GenericBSDSocketAddress : public BSDSocketAddress @@ -101,7 +186,7 @@ namespace senf { ///@} /////////////////////////////////////////////////////////////////////////// - ///\name Generic \c sockaddr interface + ///\name Generic sockaddr interface ///\{ struct sockaddr const * sockaddr_p() const;