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