E-MailRelay
gaddress.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 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 "gstringview.h"
26#include "gstringarray.h"
27#include "gbasicaddress.h"
28#include "gexception.h"
29#include <string>
30#include <memory>
31
32namespace GNet
33{
34 class Address ;
35 class Address4 ;
36 class Address6 ;
37 class AddressLocal ;
38 class AddressStorage ;
39 class AddressStorageImp ;
40}
41
42//| \class GNet::Address
43/// The GNet::Address class encapsulates a TCP/UDP transport address. The
44/// address is exposed as a 'sockaddr' structure for low-level socket
45/// operations.
46///
47/// A multi-pimple pattern is used for the implementation, with implementation
48/// classes including GNet::Address4 and GNet::Address6. In an IPv4-only build
49/// the GNet::Address6 can be forward-declared but not defined, with all methods
50/// forwarded to the GNet::Address4 sub-object.
51///
52/// Unix domain addresses are supported by the GNet::AddressLocal implementation
53/// class. Port numbers are not expected when parsing and port numbers are not
54/// included in the display string. Unix domain addresses are only allowed
55/// to be absolute filesystem paths starting with '/' and with no unprintable
56/// characters, or the well-defined zero-length address (for unbound sockets)
57/// which is given the display string of "/". Paths with funny characters or
58/// linux-specific abstract addresses (see man unix(7)) will throw.
59///
60/// \see GNet::Resolver
61///
63{
64public:
65 enum class Family
66 {
67 ipv4 ,
68 ipv6 ,
69 local
70 } ;
71 struct Domain /// Overload discriminator for Address::supports()
72 {} ;
73
74 G_EXCEPTION( Error , tx("address error") )
75 G_EXCEPTION( BadString , tx("invalid address") )
76 G_EXCEPTION_CLASS( BadFamily , tx("unsupported address family") )
77
78 static bool supports( Family ) noexcept ;
79 ///< Returns true if the implementation supports the given
80 ///< address family.
81
82 static bool supports( int af , int dummy ) noexcept ;
83 ///< Returns true if the implementation supports the given
84 ///< address family given as AF_INET etc.
85
86 static bool supports( const Domain & , int domain ) noexcept ;
87 ///< Returns true if the implementation supports the given
88 ///< address domain given as PF_INET etc.
89
90 Address( const Address & ) ;
91 ///< Copy constructor.
92
93 explicit Address( const AddressStorage & ) ;
94 ///< Constructor taking a storage object.
95
96 Address( const sockaddr * addr , socklen_t len ) ;
97 ///< Constructor using a given sockaddr. Throws an exception if an
98 ///< invalid structure. See also: validData()
99
100 Address( const sockaddr * addr , socklen_t len , bool fixup ) ;
101 ///< An overload that conditionally applies the bsd ipv6 scope-id
102 ///< fixup.
103
104 Address( Family , unsigned int port ) ;
105 ///< Constructor for a wildcard address like INADDR_ANY with the
106 ///< given port number. Throws an exception if an invalid port number.
107 ///< Postcondition: isAny()
108 /// \see validPort()
109
110 Address( Address && ) noexcept ;
111 ///< Move constructor.
112
114 ///< Destructor.
115
116 Address & operator=( const Address & ) ;
117 ///< Assignment operator.
118
119 Address & operator=( Address && ) noexcept ;
120 ///< Move assignment operator.
121
122 operator G::BasicAddress() const ;
123 ///< Returns a G::BasicAddress.
124
125 struct NotLocal /// Overload discriminator for Address::parse()
126 {} ;
127
128 static Address parse( std::string_view display_string ) ;
129 ///< Factory function for any address family. Throws if
130 ///< an invalid string. See also validString().
131
132 static Address parse( std::string_view display_string , NotLocal ) ;
133 ///< Factory function for Family::ipv4 or Family::ipv6.
134 ///< Throws if an invalid string. See also validString().
135
136 static Address parse( std::string_view host_part_string , unsigned int port ) ;
137 ///< Factory function for Family::ipv4 or Family::ipv6.
138 ///< Throws if an invalid string. See also validStrings().
139
140 static Address parse( std::string_view host_part_string , std::string_view port ) ;
141 ///< Factory function for Family::ipv4 or Family::ipv6.
142 ///< Throws if an invalid string. See also validStrings().
143
144 static bool isFamilyLocal( std::string_view display_string ) noexcept ;
145 ///< Returns true if the given address display string looks
146 ///< will parse to Family::local and Family::local is
147 ///< supported. The address may still fail to parse if
148 ///< it is invalid.
149
150 static Address defaultAddress() ;
151 ///< Returns a default address, being the IPv4 wildcard address
152 ///< with a zero port number.
153
154 static Address loopback( Family , unsigned int port = 0U ) ;
155 ///< Returns a loopback address.
156
157 const sockaddr * address() const ;
158 ///< Returns the sockaddr address. Typically used when making socket
159 ///< system calls. Never returns nullptr.
160
161 sockaddr * address() ;
162 ///< This is a non-const version of address() for compiling on systems
163 ///< which are not properly const-clean.
164
165 socklen_t length() const;
166 ///< Returns the size of the sockaddr address. See address().
167
168 std::string displayString( bool with_scope_id = false ) const ;
169 ///< Returns a printable string that represents the transport
170 ///< address.
171
172 std::string hostPartString() const ;
173 ///< Returns a printable string that represents the network
174 ///< address.
175
176 std::string queryString() const ;
177 ///< Returns a string that can be used as a prefix for rDNS or
178 ///< DNSBL queries.
179
180 unsigned int port() const;
181 ///< Returns port part of the address.
182
183 static int domain( Family ) noexcept ;
184 ///< Returns the address 'domain' for the given family, eg. PF_INET
185 ///< for Family::ipv4.
186
187 Family family() const noexcept ;
188 ///< Returns the address family enumeration.
189
190 int af() const noexcept ;
191 ///< Returns the address family number such as AF_INET or AFINET6.
192
193 static bool validPort( unsigned int n ) ;
194 ///< Returns true if the port number is within the valid range. This
195 ///< can be used to avoid exceptions from the relevant constructors.
196
197 static bool validString( std::string_view display_string , std::string * reason = nullptr ) ;
198 ///< Returns true if the transport-address display string is valid.
199 ///< This can be used to avoid exceptions from the relevant constructor.
200
201 static bool validString( std::string_view display_string , NotLocal , std::string * reason = nullptr ) ;
202 ///< Returns true if the transport-address display string is valid.
203 ///< This can be used to avoid exceptions from the relevant constructor.
204
205 static bool validStrings( std::string_view ip , std::string_view port_string , std::string * reason = nullptr ) ;
206 ///< Returns true if the combined network-address string and port string
207 ///< is valid. This can be used to avoid exceptions from the relevant
208 ///< constructor.
209
210 static bool validData( const sockaddr * , socklen_t len ) ;
211 ///< Returns true if the sockaddr data is valid. This can be used
212 ///< to avoid exceptions from the relevant constructor.
213
214 bool sameHostPart( const Address & other ) const ;
215 ///< Returns true if the two addresses have the same host part
216 ///< (ie. the network address, ignoring the port number).
217
218 Address & setPort( unsigned int port ) ;
219 ///< Sets the port number. Throws an exception if an invalid
220 ///< port number (ie. too big).
221
222 bool setZone( const std::string & ) ;
223 ///< Sets the zone. The parameter is normally a decimal string
224 ///< representation of the zone-id, aka scope-id (eg. "1"), but
225 ///< if not numeric then it is treated as an interface name
226 ///< which is mapped to a zone-id by if_nametoindex(3). Returns
227 ///< false on error. Returns true if zones are not used by the
228 ///< address family.
229
230 Address & setScopeId( unsigned long ) ;
231 ///< Sets the scope-id.
232
233 unsigned long scopeId( unsigned long default_ = 0UL ) const ;
234 ///< Returns the scope-id. Returns the default if scope-ids are not
235 ///< supported by the underlying address type.
236
237 G::StringArray wildcards() const ;
238 ///< Returns an ordered list of wildcard strings that match this
239 ///< address. The fully-address-specific string (eg. "192.168.0.1")
240 ///< comes first, and the most general match-all wildcard like
241 ///< "*.*.*.*" or "128.0.0.0/1" comes last.
242
243 unsigned int bits() const ;
244 ///< Returns the number of leading bits set, relevant only
245 ///< to netmask addresses.
246
247 bool isLoopback() const ;
248 ///< Returns true if this is a loopback address.
249
250 bool isLinkLocal() const ;
251 ///< Returns true if this is a link-local address.
252
253 bool isUniqueLocal() const ;
254 ///< Returns true if this is a locally administered address.
255
256 bool isAny() const ;
257 ///< Returns true if this is the address family's 'any' address.
258
259 bool isLocal( std::string & reason ) const ;
260 ///< Returns true if this seems to be a 'local' address, ie. an
261 ///< address that is likely to be more trusted. Returns an
262 ///< explanation by reference otherwise.
263
264 bool isMulticast() const ;
265 ///< Returns true if this is a multicast address.
266
267 bool is4() const noexcept ;
268 ///< Returns true if family() is ipv4.
269
270 bool is6() const noexcept ;
271 ///< Returns true if family() is ipv6.
272
273 bool same( const Address & , bool ipv6_compare_with_scope ) const ;
274 ///< Comparison function.
275
276 bool operator==( const Address & ) const ;
277 ///< Comparison operator.
278
279 bool operator!=( const Address & ) const ;
280 ///< Comparison operator.
281
282 void swap( Address & other ) noexcept ;
283 ///< Swaps this with other.
284
285private:
286 Address( Family , unsigned int , int ) ; // loopback()
287 Address( std::string_view display_string , bool with_local ) ; // parse(), parse(NotLocal)
288 Address( std::string_view ip , std::string_view port ) ; // parse(ip,port)
289 Address( std::string_view ip , unsigned int port ) ; // parse(ip,port)
290
291private:
292 std::unique_ptr<Address4> m_ipv4 ;
293 std::unique_ptr<Address6> m_ipv6 ;
294 std::unique_ptr<AddressLocal> m_local ;
295} ;
296
297namespace GNet
298{
299 inline void swap( Address & a , Address & b ) noexcept
300 {
301 a.swap(b) ;
302 }
303}
304
305//| \class GNet::AddressStorage
306/// A helper class for calling accept(), getsockname() and getpeername()
307/// and hiding the definition of sockaddr_storage.
308///
310{
311public:
313 ///< Default constructor, with n() reflecting the size of the
314 ///< largest supported address type.
315
317 ///< Destructor.
318
319 sockaddr * p1() ;
320 ///< Returns the sockaddr pointer for accept()/getsockname()/getpeername()
321 ///< to write into.
322
323 socklen_t * p2() ;
324 ///< Returns the length pointer for accept()/getsockname()/getpeername()
325 ///< to write into.
326
327 const sockaddr * p() const ;
328 ///< Returns the pointer, typically set via p1().
329
330 socklen_t n() const ;
331 ///< Returns the length, typically modified via p2().
332
333public:
334 AddressStorage( const AddressStorage & ) = delete ;
335 AddressStorage( AddressStorage && ) = delete ;
336 AddressStorage & operator=( const AddressStorage & ) = delete ;
337 AddressStorage & operator=( AddressStorage && ) = delete ;
338
339private:
340 std::unique_ptr<AddressStorageImp> m_imp ;
341} ;
342
343#endif
A 'sockaddr' wrapper class for IPv4 addresses.
Definition: gaddress4.h:38
A 'sockaddr' wrapper class for IPv6 addresses.
Definition: gaddress6.h:38
A 'sockaddr' wrapper class for local-domain addresses.
Definition: gaddresslocal.h:56
A helper class for calling accept(), getsockname() and getpeername() and hiding the definition of soc...
Definition: gaddress.h:310
~AddressStorage()
Destructor.
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:63
bool setZone(const std::string &)
Sets the zone.
Definition: gaddress.cpp:228
Address & setScopeId(unsigned long)
Sets the scope-id.
Definition: gaddress.cpp:238
bool is6() const noexcept
Returns true if family() is ipv6.
Definition: gaddress.cpp:317
bool isLinkLocal() const
Returns true if this is a link-local address.
Definition: gaddress.cpp:274
int af() const noexcept
Returns the address family number such as AF_INET or AFINET6.
Definition: gaddress.cpp:482
std::string queryString() const
Returns a string that can be used as a prefix for rDNS or DNSBL queries.
Definition: gaddress.cpp:374
G::StringArray wildcards() const
Returns an ordered list of wildcard strings that match this address.
Definition: gaddress.cpp:490
static bool validData(const sockaddr *, socklen_t len)
Returns true if the sockaddr data is valid.
Definition: gaddress.cpp:458
static int domain(Family) noexcept
Returns the address 'domain' for the given family, eg.
Definition: gaddress.cpp:466
static bool validString(std::string_view display_string, std::string *reason=nullptr)
Returns true if the transport-address display string is valid.
Definition: gaddress.cpp:383
static bool validStrings(std::string_view ip, std::string_view port_string, std::string *reason=nullptr)
Returns true if the combined network-address string and port string is valid.
Definition: gaddress.cpp:398
static Address loopback(Family, unsigned int port=0U)
Returns a loopback address.
Definition: gaddress.cpp:208
bool is4() const noexcept
Returns true if family() is ipv4.
Definition: gaddress.cpp:312
static bool validPort(unsigned int n)
Returns true if the port number is within the valid range.
Definition: gaddress.cpp:453
bool isUniqueLocal() const
Returns true if this is a locally administered address.
Definition: gaddress.cpp:294
void swap(Address &other) noexcept
Swaps this with other.
Definition: gaddress.cpp:161
socklen_t length() const
Returns the size of the sockaddr address. See address().
Definition: gaddress.cpp:426
bool isLocal(std::string &reason) const
Returns true if this seems to be a 'local' address, ie.
Definition: gaddress.cpp:265
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number.
Definition: gaddress.cpp:203
Address & operator=(const Address &)
Assignment operator.
Definition: gaddress.cpp:169
bool isAny() const
Returns true if this is the address family's 'any' address.
Definition: gaddress.cpp:303
static bool isFamilyLocal(std::string_view display_string) noexcept
Returns true if the given address display string looks will parse to Family::local and Family::local ...
Definition: gaddress.cpp:198
static Address parse(std::string_view display_string)
Factory function for any address family.
Definition: gaddress.cpp:178
static bool supports(Family) noexcept
Returns true if the implementation supports the given address family.
Definition: gaddress.cpp:33
bool sameHostPart(const Address &other) const
Returns true if the two addresses have the same host part (ie.
Definition: gaddress.cpp:346
unsigned int bits() const
Returns the number of leading bits set, relevant only to netmask addresses.
Definition: gaddress.cpp:247
std::string displayString(bool with_scope_id=false) const
Returns a printable string that represents the transport address.
Definition: gaddress.cpp:356
unsigned int port() const
Returns port part of the address.
Definition: gaddress.cpp:435
std::string hostPartString() const
Returns a printable string that represents the network address.
Definition: gaddress.cpp:365
bool isMulticast() const
Returns true if this is a multicast address.
Definition: gaddress.cpp:284
bool isLoopback() const
Returns true if this is a loopback address.
Definition: gaddress.cpp:256
const sockaddr * address() const
Returns the sockaddr address.
Definition: gaddress.cpp:417
unsigned long scopeId(unsigned long default_=0UL) const
Returns the scope-id.
Definition: gaddress.cpp:444
Address & setPort(unsigned int port)
Sets the port number.
Definition: gaddress.cpp:218
Family family() const noexcept
Returns the address family enumeration.
Definition: gaddress.cpp:474
bool same(const Address &, bool ipv6_compare_with_scope) const
Comparison function.
Definition: gaddress.cpp:322
Network classes.
Definition: gdef.h:1243
Low-level classes.
Definition: garg.h:36
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstringarray.h:30
constexpr const char * tx(const char *p) noexcept
A briefer alternative to G::gettext_noop().
Definition: ggettext.h:84
STL namespace.
Overload discriminator for Address::supports()
Definition: gaddress.h:72
Overload discriminator for Address::parse()
Definition: gaddress.h:126