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