moved statistics classes from NetEmu to SENF
[senf.git] / Socket / Protocols / BSDSocketAddress.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief BSDSocketAddress public header */
25
26 #ifndef HH_SENF_Socket_Protocols_BSDSocketAddress_
27 #define HH_SENF_Socket_Protocols_BSDSocketAddress_ 1
28
29 // Custom includes
30 #include <boost/type_traits/alignment_of.hpp>
31 #include <boost/type_traits/type_with_alignment.hpp>
32 #include "../../Utils/safe_bool.hh"
33 #include <sys/socket.h>
34 #include <iostream>
35
36 //#include "BSDSocketAddress.mpp"
37 ///////////////////////////////hh.p////////////////////////////////////////
38
39 namespace senf {
40
41     /** \brief Socket addressing, BSD style
42         
43         BSDSocketAddress is the base class of all BSD \c sockaddr based addressing classes. The \c
44         sockaddr addressing interface is split into several parts
45
46         \li The BSDSocketAddress provides a read-only and generic \c sockaddr interface
47         \li Address family specific derived classes implement addressing of a specific type. These
48             are INet4SocketAddress (\c AF_INET), INet6SocketAddress (\c AF_INET6), UNSocketAddress
49             (\c AF_UNIX) and LLSocketAddress (\c AF_PACKET)
50         \li GenericBSDSocketAddress provides writable support for generic addresses.
51
52         It is \e not possible to create or store BSDSocketAddress instances: You must either store
53         an address in one of the specifically typed subclasses or using GenericBSDSocketAddress.
54
55         A BSDSocketAddress or GenericBSDSocketAddress can be cast (like a downcast) to (the correct)
56         type specific cast using sockaddr_cast:
57
58         \code
59         void foo(senf::BSDSOcketAddress const & addr)
60         {
61             if (addr.family() == senf::INet4SocketAddress::addressFamily) {
62                 senf::INet4SocketAddress i4addr (
63                     senf::sockaddr_cast<senf::INet4SocketAddress>(addr) );
64                 ...
65             }
66         }
67         \endcode
68         
69         All these classes provide a generic \c sockaddr API to interface with legacy \c sockaddr
70         based code (e.g. the BSD socket API). In this base-class, this interface is read-only, the
71         derived classes however provide a read-write interface.
72
73         \ingroup addr_group
74       */
75     class BSDSocketAddress
76         : public senf::comparable_safe_bool<BSDSocketAddress>
77     {
78     public:
79         bool operator==(BSDSocketAddress const & other) const; ///< Compare two arbitrary addresses
80                                         /**< For addresses to be considered equal, they must have
81                                              the same family, length and the data must be
82                                              identical. */
83         bool operator!=(BSDSocketAddress const & other) const; ///< Inverse of operator==
84
85         bool boolean_test() const;      ///< Return \c true, if address is not empty
86                                         /**< An address is considered empty if
87                                              \li the family is AF_UNSPEC
88                                              \li or the size is 0
89                                              \li or all data bytes are 0 */
90
91         short family() const;           ///< Return the address family.
92                                         /**< This value is found in the \c addressFamily member of
93                                              each typed derived class
94                                              (e.g. INet4Address::addressFamily) */
95
96         ///////////////////////////////////////////////////////////////////////////
97         ///\name Generic sockaddr interface
98         ///\{
99
100         struct sockaddr const * sockaddr_p() const;
101         socklen_t socklen() const;
102         socklen_t const * socklen_p() const;
103
104         ///\}
105
106     protected:
107         BSDSocketAddress(socklen_t len, short family);
108         BSDSocketAddress(BSDSocketAddress const & other);
109         BSDSocketAddress & operator=(BSDSocketAddress const & other);
110
111         struct sockaddr * sockaddr_p();
112         socklen_t * socklen_p();
113
114         void socklen(socklen_t len);
115
116     private:
117         
118         // The following incantation is needed to fix the alignment of the sockaddr data members
119         // which will be added by the derived classes later: The alignment must be forced
120         // to coincide with the struct sockaddr_storage alignment (which must have the largest
121         // alignment of all sockaddr types).
122         union {
123             socklen_t len_;
124             boost::type_with_alignment<boost::alignment_of<struct sockaddr_storage>::value> a_;
125             char _b[boost::alignment_of<struct sockaddr_storage>::value];
126         };
127     };
128
129     /** \brief Safe socket address down-cast
130
131         sockaddr_cast allows to safely cast a socket address to it's derived type. Only the family
132         specific derived addressing classes are permissible for \a Target.
133
134         This cast is especially useful to cast a GenericBSDSocketAddress to it's concrete type.
135
136         \related BSDSocketAddress
137      */
138     template <class Target>
139     Target & sockaddr_cast(BSDSocketAddress & source);
140
141     /** \brief Safe socket address down-cast (const)
142         \see sockaddr_cast()
143         \related BSDSocketAddress
144      */
145     template <class Target>
146     Target const & sockaddr_cast(BSDSocketAddress const & source);
147
148     /** \brief Output generic socket address
149
150         This stream operator will output a generic BSDSocketAddress in a family depending format.
151         
152         \related BSDSocketAddress
153      */
154     std::ostream & operator<<(std::ostream & os, BSDSocketAddress const & addr);
155
156     /** \brief Generic BSD \c sockaddr storage
157
158         While BSDSocketAddress provides read-only generic \c sockaddr access,
159         GenericBSDSocketAddress allows to store (write) arbitrary socket addresses. (It is
160         internally based on \c sockaddr_storage). 
161
162         To access the stored address, use sockaddr_cast to cast the GenericBSDSocketAddress to the
163         correct family specific address class.
164
165         \ingroup addr_group
166       */
167     class GenericBSDSocketAddress
168         : public BSDSocketAddress
169     {
170     public:
171         ///////////////////////////////////////////////////////////////////////////
172         ///\name Structors and default members
173         ///@{
174
175         GenericBSDSocketAddress();
176         GenericBSDSocketAddress(BSDSocketAddress const & other);
177         GenericBSDSocketAddress& operator=(const BSDSocketAddress & other);
178
179         GenericBSDSocketAddress(const GenericBSDSocketAddress& other);
180         GenericBSDSocketAddress& operator=(const GenericBSDSocketAddress& other);
181         
182         ///@}
183         ///////////////////////////////////////////////////////////////////////////
184         ///\name Generic sockaddr interface
185         ///\{
186
187         struct sockaddr const * sockaddr_p() const;
188         struct sockaddr * sockaddr_p();
189
190         using BSDSocketAddress::socklen_p;
191
192         ///\}
193
194     protected:
195
196     private:
197         struct sockaddr_storage addr_;
198     };
199
200 }
201
202 ///////////////////////////////hh.e////////////////////////////////////////
203 #include "BSDSocketAddress.cci"
204 //#include "BSDSocketAddress.ct"
205 //#include "BSDSocketAddress.cti"
206 #endif
207
208 \f
209 // Local Variables:
210 // mode: c++
211 // fill-column: 100
212 // comment-column: 40
213 // c-file-style: "senf"
214 // indent-tabs-mode: nil
215 // ispell-local-dictionary: "american"
216 // compile-command: "scons -u test"
217 // End: