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