40f0a7ae819170ef9f64581e2384a7a983bf49a9
[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     /** \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         \implementation This implementation is based on sockaddr_in, which is needed since it needs
53             to provide a non-const struct sockaddr * for legacy compatibility.
54
55         \ingroup addr_group
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 & addr); ///< 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 address syntax is
70                                                  invalid
71                                              \throws INet4Address::UnknownHostnameException if the
72                                                  address cannot be resolved. */
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 socket address
116
117         This class wraps the standard \c sockaddr_in6 structure. INet6SocketAddress provides access
118         to all members of the sockaddr_in6 structure. Additionally, INet6SocketAddress supports the
119         string representations
120
121         \par ""
122             <tt>[</tt> <i>address</i> [ <tt>%</tt> <i>zone-id</i> ] <tt>]:</tt> <i>port</i> \n
123             <i>hostname</i> <tt>:</tt> <i>port</i>
124
125         Where \e address is an arbitrary numeric IPv6 address, \e zone-id is an optional network
126         interface name and \e port is the port number. So some example addresses are
127         
128         \par ""
129             <tt>[2001:db8:1::1]:80</tt> \n
130             <tt>www.6bone.net:80</tt> \n
131             <tt>[fe80::1\%eth0]:443</tt>
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         \idea Implement a INet6Address_ref class which has an interface identical to INet6Address
139             and is convertible to INet6Address (the latter has a conversion constructor taking the
140             former as arg). This class however references an external in6_addr instead of containing
141             one itself. This can be used in INet6SocketAddress to increase the performance of some
142             operations.
143
144         \ingroup addr_group
145      */
146     class INet6SocketAddress
147     {
148     public:
149         ///////////////////////////////////////////////////////////////////////////
150         // Types
151
152         ///////////////////////////////////////////////////////////////////////////
153         ///\name Structors and default members
154         ///@{
155
156         INet6SocketAddress();           ///< Create empty instance
157         explicit INet6SocketAddress(std::string const & addr, 
158                                     INet6Address::Resolve_t resolve = INet6Address::ResolveINet6);
159                                         ///< Initialize/convert from string representation
160                                         /**< \throws SyntaxException if the address syntax is
161                                                  invalid
162                                              \throws INet6Address::UnknownHostnameException if the
163                                                  address cannot be resolved.
164                                              \param[in] addr Address to parse
165                                              \param[in] resolve If this is
166                                                  INet6Address::ResolveINet4, support IpV4
167                                                  addresses. See INet6Address. */
168         INet6SocketAddress(INet6Address const & addr, unsigned port);
169                                         ///< Initialize from address and port
170         INet6SocketAddress(INet6Address const & addr, unsigned port, std::string const & iface);
171                                         ///< Initialize explicitly from given parameters
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         INet6Address address() const;    ///< Get printable address representation
182
183         void address(INet6Address const & addr); ///< Change address
184
185         unsigned port() const;          ///< Get port number
186         void port(unsigned poirt);      ///< Change port number
187
188         std::string iface() const;      ///< Get interface name
189         void iface(std::string const & iface); ///< Change interface
190
191         ///\name Generic SocketAddress interface
192         ///@{
193
194         struct sockaddr * sockaddr_p();
195         struct sockaddr const * sockaddr_p() const;
196         unsigned sockaddr_len() const;
197
198         ///@}
199
200         struct SyntaxException : public std::exception
201         { virtual char const * what() const throw() 
202                 { return "Invalid IpV6 socket address syntax"; } };
203
204     protected:
205
206     private:
207         void assignIface(std::string const & iface);
208
209         struct sockaddr_in6 sockaddr_;
210     };
211
212     /** \brief Output INet6SocketAddress instance as it's string representation
213         \related INet6SocketAddress
214      */
215     std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr);
216
217     /// \addtogroup policy_impl_group
218     /// @{
219
220     /** \brief Addressing policy supporting IPv4 addressing
221
222         \par Address Type:
223             INet4Address
224
225         This addressing policy implements addressing using Internet V4
226         addresses.
227
228         The various members are directly imported from
229         GenericAddressingPolicy which see for a detailed
230         documentation.
231      */
232     struct INet4AddressingPolicy
233         : public AddressingPolicyBase,
234           private GenericAddressingPolicy<INet4SocketAddress>
235     {
236         typedef INet4SocketAddress Address;
237
238         using GenericAddressingPolicy<INet4SocketAddress>::peer;
239         using GenericAddressingPolicy<INet4SocketAddress>::local;
240         using GenericAddressingPolicy<INet4SocketAddress>::connect;
241         using GenericAddressingPolicy<INet4SocketAddress>::bind;
242     };
243
244     /** \brief Addressing policy supporting IPv6 addressing
245
246         \par Address Type:
247             INet6SocketAddress
248
249         This addressing policy implements addressing using Internet V6
250         addresses.
251
252         The various members are directly imported from
253         GenericAddressingPolicy which see for a detailed
254         documentation.
255      */
256     struct INet6AddressingPolicy
257         : public AddressingPolicyBase,
258           private GenericAddressingPolicy<INet6SocketAddress>
259     {
260         typedef INet6SocketAddress Address;
261
262         using GenericAddressingPolicy<INet6SocketAddress>::peer;
263         using GenericAddressingPolicy<INet6SocketAddress>::local;
264         using GenericAddressingPolicy<INet6SocketAddress>::connect;
265         using GenericAddressingPolicy<INet6SocketAddress>::bind;
266     };
267
268     /// @}
269
270 }
271
272 ///////////////////////////////hh.e////////////////////////////////////////
273 #include "INetAddressing.cci"
274 //#include "INetAddressing.ct"
275 //#include "INetAddressing.cti"
276 //#include "INetAddressing.mpp"
277 #endif
278
279 \f
280 // Local Variables:
281 // mode: c++
282 // fill-column: 100
283 // c-file-style: "senf"
284 // indent-tabs-mode: nil
285 // ispell-local-dictionary: "american"
286 // compile-command: "scons -u test"
287 // comment-column: 40
288 // End: