E-MailRelay
gaddress.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gaddress.h
19///
20
21#ifndef G_NET_ADDRESS_H
22#define G_NET_ADDRESS_H
23
24#include "gdef.h"
25#include "gstrings.h"
26#include "gexception.h"
27#include <string>
28#include <memory>
29
30namespace GNet
31{
32 class Address ;
33 class Address4 ;
34 class Address6 ;
35 class AddressLocal ;
36 class AddressStorage ;
37 class AddressStorageImp ;
38}
39
40//| \class GNet::Address
41/// The GNet::Address class encapsulates a TCP/UDP transport address. The
42/// address is exposed as a 'sockaddr' structure for low-level socket
43/// operations.
44///
45/// A multi-pimple pattern is used for the implementation, with implementation
46/// classes including GNet::Address4 and GNet::Address6. In an IPv4-only build
47/// the GNet::Address6 can be forward-declared but not defined, with all methods
48/// forwarded to the GNet::Address4 sub-object.
49///
50/// \see GNet::Resolver
51///
53{
54public:
55 enum class Family
56 {
57 ipv4 ,
58 ipv6 ,
59 local
60 } ;
61 struct Domain /// Overload discriminator for Address::supports()
62 {} ;
63
64 G_EXCEPTION( Error , "address error" ) ;
65 G_EXCEPTION( BadString , "invalid address" ) ;
66 G_EXCEPTION_CLASS( BadFamily , "unsupported address family" ) ;
67
68 static bool supports( Family ) ;
69 ///< Returns true if the implementation supports the given
70 ///< address family.
71
72 static bool supports( int af , int dummy ) ;
73 ///< Returns true if the implementation supports the given
74 ///< address family given as AF_INET etc.
75
76 static bool supports( const Domain & , int domain ) ;
77 ///< Returns true if the implementation supports the given
78 ///< address domain given as PF_INET etc.
79
80 Address( const Address & ) ;
81 ///< Copy constructor.
82
83 explicit Address( const AddressStorage & ) ;
84 ///< Constructor taking a storage object.
85
86 Address( const sockaddr * addr , socklen_t len ) ;
87 ///< Constructor using a given sockaddr. Throws an exception if an
88 ///< invalid structure. See also: validData()
89
90 Address( const sockaddr * addr , socklen_t len , bool fixup ) ;
91 ///< An overload that conditionally applies the bsd ipv6 scope-id
92 ///< fixup.
93
94 Address( Family , unsigned int port ) ;
95 ///< Constructor for a wildcard address like INADDR_ANY with the
96 ///< given port number. Throws an exception if an invalid port number.
97 ///< Postcondition: isAny()
98 /// \see validPort()
99
100 Address( Address && ) noexcept ;
101 ///< Move constructor.
102
104 ///< Destructor.
105
106 Address & operator=( const Address & ) ;
107 ///< Assignment operator.
108
109 Address & operator=( Address && ) noexcept ;
110 ///< Move assignment operator.
111
112 struct NotLocal /// Overload discriminator for Address::parse()
113 {} ;
114
115 static Address parse( const std::string & display_string ) ;
116 ///< Factory function for any address family. Throws if
117 ///< an invalid string. See also validString().
118
119 static Address parse( const std::string & display_string , NotLocal ) ;
120 ///< Factory function for Family::ipv4 or Family::ipv6.
121 ///< Throws if an invalid string. See also validString().
122
123 static Address parse( const std::string & host_part_string , unsigned int port ) ;
124 ///< Factory function for Family::ipv4 or Family::ipv6.
125 ///< Throws if an invalid string. See also validStrings().
126
127 static Address parse( const std::string & host_part_string , const std::string & port ) ;
128 ///< Factory function for Family::ipv4 or Family::ipv6.
129 ///< Throws if an invalid string. See also validStrings().
130
131 static bool isFamilyLocal( const std::string & display_string ) ;
132 ///< Returns true if the given address display string looks
133 ///< will parse to Family::local and Family::local is
134 ///< supported. The address may still fail to parse if
135 ///< it is invalid.
136
137 static Address defaultAddress() ;
138 ///< Returns a default address, being the IPv4 wildcard address
139 ///< with a zero port number.
140
141 static Address loopback( Family , unsigned int port = 0U ) ;
142 ///< Returns a loopback address.
143
144 const sockaddr * address() const ;
145 ///< Returns the sockaddr address. Typically used when making socket
146 ///< system calls. Never returns nullptr.
147
148 sockaddr * address() ;
149 ///< This is a non-const version of address() for compiling on systems
150 ///< which are not properly const-clean.
151
152 socklen_t length() const;
153 ///< Returns the size of the sockaddr address. See address().
154
155 std::string displayString( bool with_scope_id = false ) const ;
156 ///< Returns a string which represents the transport address.
157
158 std::string hostPartString( bool raw = false ) const ;
159 ///< Returns a string which represents the network address.
160 ///< For unix-domain sockets this returns the address path
161 ///< and if the 'raw' parameter is set then any non-printing
162 ///< characters are not escaped.
163
164 std::string queryString() const ;
165 ///< Returns a string that can be used as a prefix for rDNS or
166 ///< DNSBL queries.
167
168 unsigned int port() const;
169 ///< Returns port part of the address.
170
171 static int domain( Family ) ;
172 ///< Returns the address 'domain' for the given family, eg. PF_INET
173 ///< for Family::ipv4.
174
175 Family family() const ;
176 ///< Returns the address family enumeration.
177
178 int af() const ;
179 ///< Returns the address family number such as AF_INET or AFINET6.
180
181 static bool validPort( unsigned int n ) ;
182 ///< Returns true if the port number is within the valid range. This
183 ///< can be used to avoid exceptions from the relevant constructors.
184
185 static bool validString( const std::string & display_string , std::string * reason = nullptr ) ;
186 ///< Returns true if the transport-address display string is valid.
187 ///< This can be used to avoid exceptions from the relevant constructor.
188
189 static bool validString( const std::string & display_string , NotLocal , std::string * reason = nullptr ) ;
190 ///< Returns true if the transport-address display string is valid.
191 ///< This can be used to avoid exceptions from the relevant constructor.
192
193 static bool validStrings( const std::string & ip , const std::string & port_string , std::string * reason = nullptr ) ;
194 ///< Returns true if the combined network-address string and port string
195 ///< is valid. This can be used to avoid exceptions from the relevant
196 ///< constructor.
197
198 static bool validData( const sockaddr * , socklen_t len ) ;
199 ///< Returns true if the sockaddr data is valid. This can be used
200 ///< to avoid exceptions from the relevant constructor.
201
202 bool sameHostPart( const Address & other ) const ;
203 ///< Returns true if the two addresses have the same host part
204 ///< (ie. the network address, ignoring the port number).
205
206 Address & setPort( unsigned int port ) ;
207 ///< Sets the port number. Throws an exception if an invalid
208 ///< port number (ie. too big).
209
210 bool setZone( const std::string & ) ;
211 ///< Sets the zone. The parameter is normally a decimal string
212 ///< representation of the zone-id, aka scope-id (eg. "1"), but
213 ///< if not numeric then it is treated as an interface name
214 ///< which is mapped to a zone-id by if_nametoindex(3). Returns
215 ///< false on error. Returns true if zones are not used by the
216 ///< address family.
217
218 Address & setScopeId( unsigned long ) ;
219 ///< Sets the scope-id.
220
221 unsigned long scopeId( unsigned long default_ = 0UL ) const ;
222 ///< Returns the scope-id. Returns the default if scope-ids are not
223 ///< supported by the underlying address type.
224
225 G::StringArray wildcards() const ;
226 ///< Returns an ordered list of wildcard strings that match this
227 ///< address. The fully-address-specific string (eg. "192.168.0.1")
228 ///< comes first, and the most general match-all wildcard like
229 ///< "*.*.*.*" or "128.0.0.0/1" comes last.
230
231 unsigned int bits() const ;
232 ///< Returns the number of leading bits set, relevant only
233 ///< to netmask addresses.
234
235 bool isLoopback() const ;
236 ///< Returns true if this is a loopback address.
237
238 bool isLinkLocal() const ;
239 ///< Returns true if this is a link-local address.
240
241 bool isUniqueLocal() const ;
242 ///< Returns true if this is a locally administered address.
243
244 bool isAny() const ;
245 ///< Returns true if this is the address family's 'any' address.
246
247 bool isLocal( std::string & reason ) const ;
248 ///< Returns true if this seems to be a 'local' address, ie. an
249 ///< address that is likely to be more trusted. Returns an
250 ///< explanation by reference otherwise.
251
252 bool is4() const ;
253 ///< Returns true if family() is ipv4.
254
255 bool is6() const ;
256 ///< Returns true if family() is ipv6.
257
258 bool same( const Address & , bool ipv6_compare_with_scope ) const ;
259 ///< Comparison function.
260
261 bool operator==( const Address & ) const ;
262 ///< Comparison operator.
263
264 bool operator!=( const Address & ) const ;
265 ///< Comparison operator.
266
267 void swap( Address & other ) noexcept ;
268 ///< Swaps this with other.
269
270private:
271 Address( Family , unsigned int , int ) ; // loopback()
272 explicit Address( const std::string & display_string ) ; // parse()
273 Address( const std::string & display_string , NotLocal ) ; // parse(NotLocal)
274 Address( const std::string & ip , const std::string & port ) ; // parse(ip,port)
275 Address( const std::string & ip , unsigned int port ) ; // parse(ip,port)
276
277private:
278 std::unique_ptr<Address4> m_ipv4 ;
279 std::unique_ptr<Address6> m_ipv6 ;
280 std::unique_ptr<AddressLocal> m_local ;
281} ;
282
283namespace GNet
284{
285 inline void swap( Address & a , Address & b ) noexcept
286 {
287 a.swap(b) ;
288 }
289}
290
291//| \class GNet::AddressStorage
292/// A helper class for calling accept(), getsockname() and getpeername()
293/// and hiding the definition of sockaddr_storage.
294///
296{
297public:
299 ///< Default constructor, with n() reflecting the size of the
300 ///< largest supported address type.
301
303 ///< Destructor.
304
305 sockaddr * p1() ;
306 ///< Returns the sockaddr pointer for accept()/getsockname()/getpeername()
307 ///< to write into.
308
309 socklen_t * p2() ;
310 ///< Returns the length pointer for accept()/getsockname()/getpeername()
311 ///< to write into.
312
313 const sockaddr * p() const ;
314 ///< Returns the pointer, typically set via p1().
315
316 socklen_t n() const ;
317 ///< Returns the length, typically modified via p2().
318
319public:
320 AddressStorage( const AddressStorage & ) = delete ;
321 AddressStorage( AddressStorage && ) = delete ;
322 void operator=( const AddressStorage & ) = delete ;
323 void operator=( AddressStorage && ) = delete ;
324
325private:
326 std::unique_ptr<AddressStorageImp> m_imp ;
327} ;
328
329#endif
A helper class for calling accept(), getsockname() and getpeername() and hiding the definition of soc...
Definition: gaddress.h:296
sockaddr * p1()
Returns the sockaddr pointer for accept()/getsockname()/getpeername() to write into.
Definition: gaddress.cpp:549
const sockaddr * p() const
Returns the pointer, typically set via p1().
Definition: gaddress.cpp:559
socklen_t * p2()
Returns the length pointer for accept()/getsockname()/getpeername() to write into.
Definition: gaddress.cpp:554
AddressStorage()
Default constructor, with n() reflecting the size of the largest supported address type.
Definition: gaddress.cpp:532
~AddressStorage()
Destructor.
socklen_t n() const
Returns the length, typically modified via p2().
Definition: gaddress.cpp:564
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
bool setZone(const std::string &)
Sets the zone.
Definition: gaddress.cpp:261
Address(Address &&) noexcept
Move constructor.
Address & setScopeId(unsigned long)
Sets the scope-id.
Definition: gaddress.cpp:270
bool is4() const
Returns true if family() is ipv4.
Definition: gaddress.cpp:333
Family family() const
Returns the address family enumeration.
Definition: gaddress.cpp:491
Address(const Address &)
Copy constructor.
Definition: gaddress.cpp:183
int af() const
Returns the address family number such as AF_INET or AFINET6.
Definition: gaddress.cpp:500
bool operator!=(const Address &) const
Comparison operator.
Definition: gaddress.cpp:361
bool isLinkLocal() const
Returns true if this is a link-local address.
Definition: gaddress.cpp:306
bool operator==(const Address &) const
Comparison operator.
Definition: gaddress.cpp:352
std::string queryString() const
Returns a string that can be used as a prefix for rDNS or DNSBL queries.
Definition: gaddress.cpp:393
G::StringArray wildcards() const
Returns an ordered list of wildcard strings that match this address.
Definition: gaddress.cpp:509
static bool isFamilyLocal(const std::string &display_string)
Returns true if the given address display string looks will parse to Family::local and Family::local ...
Definition: gaddress.cpp:237
static bool validData(const sockaddr *, socklen_t len)
Returns true if the sockaddr data is valid.
Definition: gaddress.cpp:475
std::string hostPartString(bool raw=false) const
Returns a string which represents the network address.
Definition: gaddress.cpp:384
static bool supports(Family)
Returns true if the implementation supports the given address family.
Definition: gaddress.cpp:33
static Address loopback(Family, unsigned int port=0U)
Returns a loopback address.
Definition: gaddress.cpp:247
static bool validPort(unsigned int n)
Returns true if the port number is within the valid range.
Definition: gaddress.cpp:470
bool isUniqueLocal() const
Returns true if this is a locally administered address.
Definition: gaddress.cpp:315
static bool validStrings(const std::string &ip, const std::string &port_string, std::string *reason=nullptr)
Returns true if the combined network-address string and port string is valid.
Definition: gaddress.cpp:417
void swap(Address &other) noexcept
Swaps this with other.
Definition: gaddress.cpp:200
socklen_t length() const
Returns the size of the sockaddr address. See address().
Definition: gaddress.cpp:443
bool isLocal(std::string &reason) const
Returns true if this seems to be a 'local' address, ie.
Definition: gaddress.cpp:297
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number.
Definition: gaddress.cpp:242
bool isAny() const
Returns true if this is the address family's 'any' address.
Definition: gaddress.cpp:324
bool is6() const
Returns true if family() is ipv6.
Definition: gaddress.cpp:338
static Address parse(const std::string &display_string)
Factory function for any address family.
Definition: gaddress.cpp:217
static bool validString(const std::string &display_string, std::string *reason=nullptr)
Returns true if the transport-address display string is valid.
Definition: gaddress.cpp:402
bool sameHostPart(const Address &other) const
Returns true if the two addresses have the same host part (ie.
Definition: gaddress.cpp:366
unsigned int bits() const
Returns the number of leading bits set, relevant only to netmask addresses.
Definition: gaddress.cpp:279
std::string displayString(bool with_scope_id=false) const
Returns a string which represents the transport address.
Definition: gaddress.cpp:375
unsigned int port() const
Returns port part of the address.
Definition: gaddress.cpp:452
bool isLoopback() const
Returns true if this is a loopback address.
Definition: gaddress.cpp:288
const sockaddr * address() const
Returns the sockaddr address.
Definition: gaddress.cpp:434
unsigned long scopeId(unsigned long default_=0UL) const
Returns the scope-id.
Definition: gaddress.cpp:461
Address & setPort(unsigned int port)
Sets the port number.
Definition: gaddress.cpp:252
static int domain(Family)
Returns the address 'domain' for the given family, eg.
Definition: gaddress.cpp:483
bool same(const Address &, bool ipv6_compare_with_scope) const
Comparison function.
Definition: gaddress.cpp:343
Network classes.
Definition: gdef.h:1115
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31
Overload discriminator for Address::supports()
Definition: gaddress.h:62
Overload discriminator for Address::parse()
Definition: gaddress.h:113