Socket/Protocols: (hopefully) fix sockaddr alignment issues on 64bit
[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         union {
119             socklen_t len_;
120             boost::type_with_alignment<boost::alignment_of<struct sockaddr_storage>::value> _;
121         };
122     };
123
124     /** \brief Safe socket address down-cast
125
126         sockaddr_cast allows to safely cast a socket address to it's derived type. Only the family
127         specific derived addressing classes are permissible for \a Target.
128
129         This cast is especially useful to cast a GenericBSDSocketAddress to it's concrete type.
130
131         \related BSDSocketAddress
132      */
133     template <class Target>
134     Target & sockaddr_cast(BSDSocketAddress & source);
135
136     /** \brief Safe socket address down-cast (const)
137         \see sockaddr_cast()
138         \related BSDSocketAddress
139      */
140     template <class Target>
141     Target const & sockaddr_cast(BSDSocketAddress const & source);
142
143     /** \brief Output generic socket address
144
145         This stream operator will output a generic BSDSocketAddress in a family depending format.
146         
147         \related BSDSocketAddress
148      */
149     std::ostream & operator<<(std::ostream & os, BSDSocketAddress const & addr);
150
151     /** \brief Generic BSD \c sockaddr storage
152
153         While BSDSocketAddress provides read-only generic \c sockaddr access,
154         GenericBSDSocketAddress allows to store (write) arbitrary socket addresses. (It is
155         internally based on \c sockaddr_storage). 
156
157         To access the stored address, use sockaddr_cast to cast the GenericBSDSocketAddress to the
158         correct family specific address class.
159
160         \ingroup addr_group
161       */
162     class GenericBSDSocketAddress
163         : public BSDSocketAddress
164     {
165     public:
166         ///////////////////////////////////////////////////////////////////////////
167         ///\name Structors and default members
168         ///@{
169
170         GenericBSDSocketAddress();
171         GenericBSDSocketAddress(BSDSocketAddress const & other);
172         GenericBSDSocketAddress& operator=(const BSDSocketAddress & other);
173
174         GenericBSDSocketAddress(const GenericBSDSocketAddress& other);
175         GenericBSDSocketAddress& operator=(const GenericBSDSocketAddress& other);
176         
177         ///@}
178         ///////////////////////////////////////////////////////////////////////////
179         ///\name Generic sockaddr interface
180         ///\{
181
182         struct sockaddr const * sockaddr_p() const;
183         struct sockaddr * sockaddr_p();
184
185         using BSDSocketAddress::socklen_p;
186
187         ///\}
188
189     protected:
190
191     private:
192         struct sockaddr_storage addr_;
193     };
194
195 }
196
197 ///////////////////////////////hh.e////////////////////////////////////////
198 #include "BSDSocketAddress.cci"
199 //#include "BSDSocketAddress.ct"
200 //#include "BSDSocketAddress.cti"
201 #endif
202
203 \f
204 // Local Variables:
205 // mode: c++
206 // fill-column: 100
207 // comment-column: 40
208 // c-file-style: "senf"
209 // indent-tabs-mode: nil
210 // ispell-local-dictionary: "american"
211 // compile-command: "scons -u test"
212 // End: