e8bd9427c5ef172b52297256c0696be63b6ee619
[senf.git] / senf / 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 <boost/operators.hpp>
33 #include <senf/Utils/safe_bool.hh>
34 #include <sys/socket.h>
35 #include <iostream>
36
37 //#include "BSDSocketAddress.mpp"
38 ///////////////////////////////hh.p////////////////////////////////////////
39
40 namespace senf {
41
42     /** \brief Socket addressing, BSD style
43
44         BSDSocketAddress is the base class of all BSD \c sockaddr based addressing classes. The \c
45         sockaddr addressing interface is split into several parts
46
47         \li The BSDSocketAddress provides a read-only and generic \c sockaddr interface
48         \li Address family specific derived classes implement addressing of a specific type. These
49             are INet4SocketAddress (\c AF_INET), INet6SocketAddress (\c AF_INET6), UNSocketAddress
50             (\c AF_UNIX) and LLSocketAddress (\c AF_PACKET)
51         \li GenericBSDSocketAddress provides writable support for generic addresses.
52
53         It is \e not possible to create or store BSDSocketAddress instances: You must either store
54         an address in one of the specifically typed subclasses or using GenericBSDSocketAddress.
55
56         A BSDSocketAddress or GenericBSDSocketAddress can be cast (like a downcast) to (the correct)
57         type specific cast using sockaddr_cast:
58
59         \code
60         void foo(senf::BSDSOcketAddress const & addr)
61         {
62             if (addr.family() == senf::INet4SocketAddress::addressFamily) {
63                 senf::INet4SocketAddress i4addr (
64                     senf::sockaddr_cast<senf::INet4SocketAddress>(addr) );
65                 ...
66             }
67         }
68         \endcode
69
70         All these classes provide a generic \c sockaddr API to interface with legacy \c sockaddr
71         based code (e.g. the BSD socket API). In this base-class, this interface is read-only, the
72         derived classes however provide a read-write interface.
73
74         \ingroup addr_group
75       */
76     class BSDSocketAddress
77         : public senf::comparable_safe_bool<BSDSocketAddress>,
78           public boost::less_than_comparable<BSDSocketAddress>,
79           public boost::equality_comparable<BSDSocketAddress>
80     {
81     public:
82         bool operator==(BSDSocketAddress const & other) const; ///< Compare two arbitrary addresses
83                                         /**< For addresses to be considered equal, they must have
84                                              the same family, length and the data must be
85                                              identical. */
86         bool operator<(BSDSocketAddress const & other) const; ///< Compare two arbitrary addresses
87                                         /**< Ordering is based on the in-memory representation.  It
88                                              is primarily useful to use addresses as keys in a map
89                                              or set. */
90
91         bool boolean_test() const;      ///< Return \c true, if address is not empty
92                                         /**< An address is considered empty if
93                                              \li the family is AF_UNSPEC
94                                              \li or the size is 0
95                                              \li or all data bytes are 0 */
96
97         short family() const;           ///< Return the address family.
98                                         /**< This value is found in the \c addressFamily member of
99                                              each typed derived class
100                                              (e.g. INet4Address::addressFamily) */
101
102         ///////////////////////////////////////////////////////////////////////////
103         ///\name Generic sockaddr interface
104         ///\{
105
106         struct sockaddr const * sockaddr_p() const;
107         socklen_t socklen() const;
108         socklen_t const * socklen_p() const;
109
110         ///\}
111
112     protected:
113         BSDSocketAddress(socklen_t len, short family);
114         BSDSocketAddress(BSDSocketAddress const & other);
115         BSDSocketAddress & operator=(BSDSocketAddress const & other);
116
117         struct sockaddr * sockaddr_p();
118         socklen_t * socklen_p();
119
120         void socklen(socklen_t len);
121
122     private:
123         // The following incantation is needed to fix the alignment of the sockaddr data members
124         // which will be added by the derived classes later: The alignment must be forced
125         // to coincide with the struct sockaddr_storage alignment (which must have the largest
126         // alignment of all sockaddr types).
127         union {
128             socklen_t len_;
129             boost::type_with_alignment<boost::alignment_of<struct sockaddr_storage>::value> a_;
130             char _b[boost::alignment_of<struct sockaddr_storage>::value];
131         };
132     };
133
134     /** \brief Safe socket address down-cast
135
136         sockaddr_cast allows to safely cast a socket address to it's derived type. Only the family
137         specific derived addressing classes are permissible for \a Target.
138
139         This cast is especially useful to cast a GenericBSDSocketAddress to it's concrete type.
140
141         \related BSDSocketAddress
142      */
143     template <class Target>
144     Target & sockaddr_cast(BSDSocketAddress & source);
145
146     /** \brief Safe socket address down-cast (const)
147         \see sockaddr_cast()
148         \related BSDSocketAddress
149      */
150     template <class Target>
151     Target const & sockaddr_cast(BSDSocketAddress const & source);
152
153     /** \brief Output generic socket address
154
155         This stream operator will output a generic BSDSocketAddress in a family depending format.
156
157         \related BSDSocketAddress
158      */
159     std::ostream & operator<<(std::ostream & os, BSDSocketAddress const & addr);
160
161     /** \brief Generic BSD \c sockaddr storage
162
163         While BSDSocketAddress provides read-only generic \c sockaddr access,
164         GenericBSDSocketAddress allows to store (write) arbitrary socket addresses. (It is
165         internally based on \c sockaddr_storage).
166
167         To access the stored address, use sockaddr_cast to cast the GenericBSDSocketAddress to the
168         correct family specific address class.
169
170         \ingroup addr_group
171       */
172     class GenericBSDSocketAddress
173         : public BSDSocketAddress
174     {
175     public:
176         ///////////////////////////////////////////////////////////////////////////
177         ///\name Structors and default members
178         ///@{
179
180         GenericBSDSocketAddress();
181         GenericBSDSocketAddress(BSDSocketAddress const & other);
182         GenericBSDSocketAddress& operator=(const BSDSocketAddress & other);
183
184         GenericBSDSocketAddress(const GenericBSDSocketAddress& other);
185         GenericBSDSocketAddress& operator=(const GenericBSDSocketAddress& other);
186
187         ///@}
188         ///////////////////////////////////////////////////////////////////////////
189         ///\name Generic sockaddr interface
190         ///\{
191
192         struct sockaddr const * sockaddr_p() const;
193         struct sockaddr * sockaddr_p();
194
195         using BSDSocketAddress::socklen_p;
196
197         ///\}
198
199     protected:
200
201     private:
202         struct sockaddr_storage addr_;
203     };
204
205 }
206
207 ///////////////////////////////hh.e////////////////////////////////////////
208 #include "BSDSocketAddress.cci"
209 //#include "BSDSocketAddress.ct"
210 //#include "BSDSocketAddress.cti"
211 #endif
212
213 \f
214 // Local Variables:
215 // mode: c++
216 // fill-column: 100
217 // comment-column: 40
218 // c-file-style: "senf"
219 // indent-tabs-mode: nil
220 // ispell-local-dictionary: "american"
221 // compile-command: "scons -u test"
222 // End: