Socket/Protocols/INet: Completely new implementation of INet6Address
[senf.git] / Socket / Protocols / INet / INetAddressing.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.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 INet[46]Address and INet[46]AddressingPolicy public header
25  */
26
27 #ifndef HH_INetAddressing_
28 #define HH_INetAddressing_ 1
29
30 // Custom includes
31 #include <string>
32 #include <exception>
33 #include <netinet/in.h>
34 #include <boost/operators.hpp>
35 #include "Socket/SocketPolicy.hh"
36 #include "Socket/ClientSocketHandle.hh"
37 #include "Socket/CommunicationPolicy.hh"
38 #include "Socket/Protocols/GenericAddressingPolicy.hh"
39 #include "INet4Address.hh"
40 #include "INet6Address.hh"
41
42 //#include "INetAddressing.mpp"
43 ///////////////////////////////hh.p////////////////////////////////////////
44
45 namespace senf {
46
47     /// \addtogroup addr_group
48     /// @{
49
50     /** \brief IPv4 socket address
51
52         INet4Address wraps the standard sockaddr_in datatype. It provides simple accessor methods
53         to access the host and port. It does \e not integrate \c gethostbyname or DNS lookup.
54         
55         \implementation This implementation is based on sockaddr_in, which is needed since it needs
56             to provide a non-const struct sockaddr * for legacy compatibility.
57      */
58     class INet4SocketAddress
59         : public boost::equality_comparable<INet4SocketAddress>, 
60           public senf::ComparableSafeBool<INet4SocketAddress>
61     {
62     public:
63         INet4SocketAddress();
64         explicit INet4SocketAddress(std::string const & address); ///< Set address and port
65                                         /**< This constructor expects a string of the form
66                                              'host:port'. The constructor will use this value to
67                                              initialize the host and port members. Since it uses the
68                                              INet4Address::from_string constructor, this call may
69                                              block while waiting for the resolver.
70                                              \throws SyntaxException if the 'host:port' syntax is
71                                                  not obeyed.
72                                              \throws INet4Address::SyntaxException if the host part
73                                                  cannot be converted to an IP address. */
74
75         INet4SocketAddress(INet4Address const & addr, unsigned port); 
76                                         ///< Set address and port explicitly
77                                         /**< \param[in] addr IP address
78                                              \param[in] port port number */
79
80         bool operator==(INet4SocketAddress const & other) const;
81                                         ///< Check INet4SocketAddress for equality
82
83         INet4Address address() const;   ///< Return address
84         unsigned port() const;          ///< Return port number
85
86         bool boolean_test() const;      ///< \c true, if address is empty (i.e. 0.0.0.0:0)
87
88         void clear();                   ///< Clear address/port to 0.0.0.0:0
89
90         void address(INet4Address const & addr); ///< Set address
91         void port(unsigned p);          ///< Set port number
92
93         /// \name Generic Address Interface
94         /// @{
95
96         struct sockaddr * sockaddr_p();
97         struct sockaddr const * sockaddr_p() const;
98         unsigned sockaddr_len() const;
99
100         /// @}
101
102         struct SyntaxException : public std::exception
103         { virtual char const * what() const throw() 
104                 { return "Invalid IpV4 socket address syntax"; } };
105
106     private:
107         struct ::sockaddr_in addr_;
108     };
109
110     /** \brief Write address and port to os
111
112         \related INet4SocketAddress
113      */
114     std::ostream & operator<<(std::ostream & os, INet4SocketAddress const & addr);
115
116     /** \brief IPv6 socket address
117
118         This class wraps the standard \c sockaddr_in6 structure. INet6SocketAddress provides access
119         to all members of the sockaddr_in6 structure. Additionally, INet6SocketAddress supports the
120         string representation
121
122         \par "" <tt>[</tt> <i>address</i> [ <tt>\@</tt> <i>interface</i> ] <tt>]:</tt> <i>port</i>
123
124         Where \e address is an arbitrary numeric IPv6 address, \e interface is an optional network
125         interface name and \e port is the port number. The interface specification is only valid if
126         \e address is link-local address. The URL representation of an IPv6 address is as above
127         without the optional interface spec.
128
129         INet6SocketAddress supports conversion constructors from it's string
130         representation. Therefore, wherever a INet6SocketAddress instance is expected, a string may
131         be used instead.
132
133         \implementation The sockaddr_in6 structure has an sin6_flowinfo member. However RFC3493 does
134             not give the use of this field and specifies, that the field should be ignored ... so
135             that's what we do. Furthermore, the GNU libc reference states, that this field is not
136             implemented in the library.
137
138         \implementation We need to return the address in host() by value since we need to return a
139             INet6Address. However, sockaddr_in6 does not have one ...
140
141         \implementation The <tt>char const *</tt> constructor overload is needed to support
142             string-literals where an INet6SocketAddress is expected (the C++ standard does not allow
143             chaining conversion constructors like <tt>char const *</tt> -> \c std::string -> \c
144             INet6SocketAddress)
145
146         \idea Implement a INet6Address_ref class which has an interface identical to INet6Address
147         and is convertible to INet6Address (the latter has a conversion constructor taking the
148         former as arg). This class however references an external in6_addr instead of containing one
149         itself. This can be used in INet6SocketAddress to increase the performance of some
150         operations.
151      */
152     class INet6SocketAddress
153     {
154     public:
155         ///////////////////////////////////////////////////////////////////////////
156         // Types
157
158         ///////////////////////////////////////////////////////////////////////////
159         ///\name Structors and default members
160         ///@{
161
162         INet6SocketAddress();           ///< Create empty instance
163         INet6SocketAddress(std::string const & addr);
164                                         ///< Initialize/convert from string representation
165         INet6SocketAddress(char const * addr); ///< Same as above to support string literals
166         INet6SocketAddress(INet6Address const & addr, unsigned port);
167                                         ///< Initialize from address and port
168         INet6SocketAddress(INet6Address const & addr, unsigned port, std::string const & iface);
169                                         ///< Initialize explicitly from given parameters
170         INet6SocketAddress(std::string const & addr, std::string const & iface);
171                                         ///< Initialize from URL representation and explit interface
172
173         ///@}
174         ///////////////////////////////////////////////////////////////////////////
175
176         bool operator==(INet6SocketAddress const & other) const; ///< Check addresses for equality
177         bool operator!=(INet6SocketAddress const & other) const; ///< Inverse of above
178
179         void clear();                   ///< Clear socket address
180
181         std::string address() const;    ///< Get printable address representation
182
183         INet6Address host() const;      ///< Get address
184         void host(INet6Address const & addr); ///< Change address
185
186         unsigned port() const;          ///< Get port number
187         void port(unsigned poirt);      ///< Change port number
188
189         std::string iface() const;      ///< Get interface name
190         void iface(std::string const & iface); ///< Change interface
191
192         ///\name Generic SocketAddress interface
193         ///@{
194
195         struct sockaddr * sockaddr_p();
196         struct sockaddr const * sockaddr_p() const;
197         unsigned sockaddr_len() const;
198
199         ///@}
200
201         struct SyntaxException : public std::exception
202         { virtual char const * what() const throw() 
203                 { return "Invalid IpV6 socket address syntax"; } };
204
205     protected:
206
207     private:
208         void assignAddr(std::string const & addr);
209         void assignIface(std::string const & iface);
210
211         struct sockaddr_in6 sockaddr_;
212     };
213
214     /** \brief Output INet6SocketAddress instance as it's string representation
215      */
216     std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr);
217
218     /// @}
219
220     /// \addtogroup policy_impl_group
221     /// @{
222
223     /** \brief Addressing policy supporting IPv4 addressing
224
225         \par Address Type:
226             INet4Address
227
228         This addressing policy implements addressing using Internet V4
229         addresses.
230
231         The various members are directly imported from
232         GenericAddressingPolicy which see for a detailed
233         documentation.
234      */
235     struct INet4AddressingPolicy
236         : public AddressingPolicyBase,
237           private GenericAddressingPolicy<INet4SocketAddress>
238     {
239         typedef INet4SocketAddress Address;
240
241         using GenericAddressingPolicy<INet4SocketAddress>::peer;
242         using GenericAddressingPolicy<INet4SocketAddress>::local;
243         using GenericAddressingPolicy<INet4SocketAddress>::connect;
244         using GenericAddressingPolicy<INet4SocketAddress>::bind;
245     };
246
247     /** \brief Addressing policy supporting IPv6 addressing
248
249         \par Address Type:
250             INet6SocketAddress
251
252         This addressing policy implements addressing using Internet V6
253         addresses.
254
255         The various members are directly imported from
256         GenericAddressingPolicy which see for a detailed
257         documentation.
258      */
259     struct INet6AddressingPolicy
260         : public AddressingPolicyBase,
261           private GenericAddressingPolicy<INet6SocketAddress>
262     {
263         typedef INet6SocketAddress Address;
264
265         using GenericAddressingPolicy<INet6SocketAddress>::peer;
266         using GenericAddressingPolicy<INet6SocketAddress>::local;
267         using GenericAddressingPolicy<INet6SocketAddress>::connect;
268         using GenericAddressingPolicy<INet6SocketAddress>::bind;
269     };
270
271     /// @}
272
273 }
274
275 ///////////////////////////////hh.e////////////////////////////////////////
276 #include "INetAddressing.cci"
277 //#include "INetAddressing.ct"
278 //#include "INetAddressing.cti"
279 //#include "INetAddressing.mpp"
280 #endif
281
282 \f
283 // Local Variables:
284 // mode: c++
285 // fill-column: 100
286 // c-file-style: "senf"
287 // indent-tabs-mode: nil
288 // ispell-local-dictionary: "american"
289 // compile-command: "scons -u test"
290 // comment-column: 40
291 // End: