Socket/Protocols/INet: Updated INet4SocketAddress to use INet4Address
[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
41 //#include "INetAddressing.mpp"
42 ///////////////////////////////hh.p////////////////////////////////////////
43
44 namespace senf {
45
46     /// \addtogroup addr_group
47     /// @{
48
49     /** \brief IPv4 socket address
50
51         INet4Address wraps the standard sockaddr_in datatype. It provides simple accessor methods
52         to access the host and port. It does \e not integrate \c gethostbyname or DNS lookup.
53         
54         \implementation This implementation is based on sockaddr_in, which is needed since it needs
55             to provide a non-const struct sockaddr * for legacy compatibility.
56      */
57     class INet4SocketAddress
58         : public boost::equality_comparable<INet4SocketAddress>, 
59           public senf::ComparableSafeBool<INet4SocketAddress>
60     {
61     public:
62         INet4SocketAddress();
63         explicit INet4SocketAddress(std::string const & address); ///< Set address and port
64                                         /**< This constructor expects a string of the form
65                                              'host:port'. The constructor will use this value to
66                                              initialize the host and port members. Since it uses the
67                                              INet4Address::from_string constructor, this call may
68                                              block while waiting for the resolver.
69                                              \throws SyntaxException if the 'host:port' syntax is
70                                                  not obeyed.
71                                              \throws INet4Address::SyntaxException if the host part
72                                                  cannot be converted to an IP address. */
73
74         INet4SocketAddress(INet4Address const & addr, unsigned port); 
75                                         ///< Set address and port explicitly
76                                         /**< \param[in] addr IP address
77                                              \param[in] port port number */
78
79         bool operator==(INet4SocketAddress const & other) const;
80                                         ///< Check INet4SocketAddress for equality
81
82         INet4Address address() const;   ///< Return address
83         unsigned port() const;          ///< Return port number
84
85         bool boolean_test() const;      ///< \c true, if address is empty (i.e. 0.0.0.0:0)
86
87         void clear();                   ///< Clear address/port to 0.0.0.0:0
88
89         void address(INet4Address const & addr); ///< Set address
90         void port(unsigned p);          ///< Set port number
91
92         /// \name Generic Address Interface
93         /// @{
94
95         struct sockaddr * sockaddr_p();
96         struct sockaddr const * sockaddr_p() const;
97         unsigned sockaddr_len() const;
98
99         /// @}
100
101         struct SyntaxException : public std::exception
102         { virtual char const * what() const throw() 
103                 { return "Invalid IpV4 socket address syntax"; } };
104
105     private:
106         struct ::sockaddr_in addr_;
107     };
108
109     /** \brief Write address and port to os
110
111         \related INet4SocketAddress
112      */
113     std::ostream & operator<<(std::ostream & os, INet4SocketAddress const & addr);
114
115     /** \brief IPv6 network address
116
117         INet6Address represents a 128bit IPv6 network address. This class supports all standard
118         numeric string representations of IPv6 addresses. This class does not integrate with \c
119         gethostbyname() and so does not support host names.
120
121         The conversion constructors allow the use of string constants wherever an INet6Address is
122         expected. Especially, it is possible to assign a string to an address to change it's value.
123
124         \implementation The <tt>char const *</tt> constructor overload is needed to support
125             string-literals where an INet6Address is expected (the C++ standard does not allow
126             chaining conversion constructors like char const * -> std::string -> INet6Address)
127      */
128     class INet6Address
129     {
130     public:
131         ///////////////////////////////////////////////////////////////////////////
132         // Types
133
134         ///////////////////////////////////////////////////////////////////////////
135         ///\name Structors and default members
136         ///@{
137
138         INet6Address();                 ///< Create empty address
139         INet6Address(std::string const & addr); ///< Create address from string representation
140         INet6Address(char const * addr); ///< Create address from string representation
141         INet6Address(struct in6_addr const & addr); ///< Create address from in6_addr
142         template <class Range>
143         explicit INet6Address(Range const & range); ///< Create address from arbitrary raw data
144                                         /**< This constructor will copy 16 bytes from the given
145                                              range and interpret them as a IPv6 address in network
146                                              byte order. This constructor is used to read an
147                                              arbitrary address from it's binary representation.
148
149                                              \param range arbitrary range, see <a
150                                                  href="http://www.boost.org/libs/range/index.html">Boost.Range</a>
151                                           */
152
153         ///@}
154         ///////////////////////////////////////////////////////////////////////////
155
156         void clear();                   ///< Clear address
157         std::string address() const;    ///< Return printable address representation
158
159         bool operator==(INet6Address const & other) const; ///< Compare addresses for equality
160         bool operator!=(INet6Address const & other) const; ///< Inverse of above
161
162         struct in6_addr & addr();       ///< Access internal address representation
163         struct in6_addr const & addr() const;
164                                         ///< Access internal address representation in const context
165         struct in6_addr * addr_p();     ///< Get pointer to internal address repr
166         struct in6_addr const * addr_p() const;
167                                         ///< Get const pointer to internal address repr
168         unsigned addr_len() const;      ///< Size of an IPv6 address (16 bytes)
169
170         struct SyntaxException : public std::exception
171         { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } };
172
173     protected:
174
175     private:
176         struct in6_addr addr_;
177     };
178
179
180     /** \brief Output INet6Address instance as it's string representation
181      */
182     std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
183
184     /** \brief IPv6 socket address
185
186         This class wraps the standard \c sockaddr_in6 structure. INet6SocketAddress provides access
187         to all members of the sockaddr_in6 structure. Additionally, INet6SocketAddress supports the
188         string representation
189
190         \par "" <tt>[</tt> <i>address</i> [ <tt>\@</tt> <i>interface</i> ] <tt>]:</tt> <i>port</i>
191
192         Where \e address is an arbitrary numeric IPv6 address, \e interface is an optional network
193         interface name and \e port is the port number. The interface specification is only valid if
194         \e address is link-local address. The URL representation of an IPv6 address is as above
195         without the optional interface spec.
196
197         INet6SocketAddress supports conversion constructors from it's string
198         representation. Therefore, wherever a INet6SocketAddress instance is expected, a string may
199         be used instead.
200
201         \implementation The sockaddr_in6 structure has an sin6_flowinfo member. However RFC3493 does
202             not give the use of this field and specifies, that the field should be ignored ... so
203             that's what we do. Furthermore, the GNU libc reference states, that this field is not
204             implemented in the library.
205
206         \implementation We need to return the address in host() by value since we need to return a
207             INet6Address. However, sockaddr_in6 does not have one ...
208
209         \implementation The <tt>char const *</tt> constructor overload is needed to support
210             string-literals where an INet6SocketAddress is expected (the C++ standard does not allow
211             chaining conversion constructors like <tt>char const *</tt> -> \c std::string -> \c
212             INet6SocketAddress)
213
214         \idea Implement a INet6Address_ref class which has an interface identical to INet6Address
215         and is convertible to INet6Address (the latter has a conversion constructor taking the
216         former as arg). This class however references an external in6_addr instead of containing one
217         itself. This can be used in INet6SocketAddress to increase the performance of some
218         operations.
219      */
220     class INet6SocketAddress
221     {
222     public:
223         ///////////////////////////////////////////////////////////////////////////
224         // Types
225
226         ///////////////////////////////////////////////////////////////////////////
227         ///\name Structors and default members
228         ///@{
229
230         INet6SocketAddress();           ///< Create empty instance
231         INet6SocketAddress(std::string const & addr);
232                                         ///< Initialize/convert from string representation
233         INet6SocketAddress(char const * addr); ///< Same as above to support string literals
234         INet6SocketAddress(INet6Address const & addr, unsigned port);
235                                         ///< Initialize from address and port
236         INet6SocketAddress(INet6Address const & addr, unsigned port, std::string const & iface);
237                                         ///< Initialize explicitly from given parameters
238         INet6SocketAddress(std::string const & addr, std::string const & iface);
239                                         ///< Initialize from URL representation and explit interface
240
241         ///@}
242         ///////////////////////////////////////////////////////////////////////////
243
244         bool operator==(INet6SocketAddress const & other) const; ///< Check addresses for equality
245         bool operator!=(INet6SocketAddress const & other) const; ///< Inverse of above
246
247         void clear();                   ///< Clear socket address
248
249         std::string address() const;    ///< Get printable address representation
250
251         INet6Address host() const;      ///< Get address
252         void host(INet6Address const & addr); ///< Change address
253
254         unsigned port() const;          ///< Get port number
255         void port(unsigned poirt);      ///< Change port number
256
257         std::string iface() const;      ///< Get interface name
258         void iface(std::string const & iface); ///< Change interface
259
260         ///\name Generic SocketAddress interface
261         ///@{
262
263         struct sockaddr * sockaddr_p();
264         struct sockaddr const * sockaddr_p() const;
265         unsigned sockaddr_len() const;
266
267         ///@}
268
269         struct SyntaxException : public std::exception
270         { virtual char const * what() const throw() 
271                 { return "Invalid IpV6 socket address syntax"; } };
272
273     protected:
274
275     private:
276         void assignAddr(std::string const & addr);
277         void assignIface(std::string const & iface);
278
279         struct sockaddr_in6 sockaddr_;
280     };
281
282     /** \brief Output INet6SocketAddress instance as it's string representation
283      */
284     std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr);
285
286     /// @}
287
288     /// \addtogroup policy_impl_group
289     /// @{
290
291     /** \brief Addressing policy supporting IPv4 addressing
292
293         \par Address Type:
294             INet4Address
295
296         This addressing policy implements addressing using Internet V4
297         addresses.
298
299         The various members are directly imported from
300         GenericAddressingPolicy which see for a detailed
301         documentation.
302      */
303     struct INet4AddressingPolicy
304         : public AddressingPolicyBase,
305           private GenericAddressingPolicy<INet4SocketAddress>
306     {
307         typedef INet4SocketAddress Address;
308
309         using GenericAddressingPolicy<INet4SocketAddress>::peer;
310         using GenericAddressingPolicy<INet4SocketAddress>::local;
311         using GenericAddressingPolicy<INet4SocketAddress>::connect;
312         using GenericAddressingPolicy<INet4SocketAddress>::bind;
313     };
314
315     /** \brief Addressing policy supporting IPv6 addressing
316
317         \par Address Type:
318             INet6SocketAddress
319
320         This addressing policy implements addressing using Internet V6
321         addresses.
322
323         The various members are directly imported from
324         GenericAddressingPolicy which see for a detailed
325         documentation.
326      */
327     struct INet6AddressingPolicy
328         : public AddressingPolicyBase,
329           private GenericAddressingPolicy<INet6SocketAddress>
330     {
331         typedef INet6SocketAddress Address;
332
333         using GenericAddressingPolicy<INet6SocketAddress>::peer;
334         using GenericAddressingPolicy<INet6SocketAddress>::local;
335         using GenericAddressingPolicy<INet6SocketAddress>::connect;
336         using GenericAddressingPolicy<INet6SocketAddress>::bind;
337     };
338
339     /// @}
340
341 }
342
343 ///////////////////////////////hh.e////////////////////////////////////////
344 #include "INetAddressing.cci"
345 #include "INetAddressing.ct"
346 //#include "INetAddressing.cti"
347 //#include "INetAddressing.mpp"
348 #endif
349
350 \f
351 // Local Variables:
352 // mode: c++
353 // fill-column: 100
354 // c-file-style: "senf"
355 // indent-tabs-mode: nil
356 // ispell-local-dictionary: "american"
357 // compile-command: "scons -u test"
358 // comment-column: 40
359 // End: