35 if( f == Address::Family::local && AddressLocal::af() == 0 )
43 return af == Address4::af() || af == Address6::af() || af == AddressLocal::af() ;
48 return domain == Address4::domain() || domain == Address6::domain() || domain == AddressLocal::domain() ;
53 if( Address4::af() && f == Address::Family::ipv4 )
54 m_ipv4 = std::make_unique<Address4>( port ) ;
55 else if( Address6::af() && f == Address::Family::ipv6 )
56 m_ipv6 = std::make_unique<Address6>( port ) ;
57 else if( AddressLocal::af() && f == Address::Family::local )
58 m_local = std::make_unique<AddressLocal>( port ) ;
60 throw Address::BadFamily() ;
65 if( storage.
p()->sa_family == 0 )
66 throw Address::BadFamily() ;
67 else if( Address4::af() && storage.
p()->sa_family == Address4::af() )
68 m_ipv4 = std::make_unique<Address4>( storage.
p() , storage.
n() ) ;
69 else if( Address6::af() && storage.
p()->sa_family == Address6::af() )
70 m_ipv6 = std::make_unique<Address6>( storage.
p() , storage.
n() ) ;
71 else if( AddressLocal::af() && storage.
p()->sa_family == AddressLocal::af() )
72 m_local = std::make_unique<AddressLocal>( storage.
p() , storage.
n() ) ;
74 throw Address::BadFamily() ;
79 if( addr ==
nullptr || len <
sizeof(sockaddr::sa_family) )
80 throw Address::Error() ;
81 else if( addr->sa_family == 0 )
82 throw Address::BadFamily() ;
83 else if( Address4::af() && addr->sa_family == Address4::af() )
84 m_ipv4 = std::make_unique<Address4>( addr , len ) ;
85 else if( Address6::af() && addr->sa_family == Address6::af() )
86 m_ipv6 = std::make_unique<Address6>( addr , len ) ;
87 else if( AddressLocal::af() && addr->sa_family == AddressLocal::af() )
88 m_local = std::make_unique<AddressLocal>( addr , len ) ;
90 throw Address::BadFamily() ;
95 if( addr ==
nullptr || len <
sizeof(sockaddr::sa_family) )
96 throw Address::Error() ;
97 else if( addr->sa_family == 0 )
98 throw Address::BadFamily() ;
99 else if( Address4::af() && addr->sa_family == Address4::af() )
100 m_ipv4 = std::make_unique<Address4>( addr , len , ipv6_scope_id_fixup ) ;
101 else if( Address6::af() && addr->sa_family == Address6::af() )
102 m_ipv6 = std::make_unique<Address6>( addr , len , ipv6_scope_id_fixup ) ;
103 else if( AddressLocal::af() && addr->sa_family == AddressLocal::af() )
104 m_local = std::make_unique<AddressLocal>( addr , len , ipv6_scope_id_fixup ) ;
106 throw Address::BadFamily() ;
114 throw Address::Error(
"empty string" ) ;
115 else if( AddressLocal::af() && isFamilyLocal(s) )
116 m_local = std::make_unique<AddressLocal>( s ) ;
117 else if( Address4::af() && Address4::validString(s,&r1) )
118 m_ipv4 = std::make_unique<Address4>( s ) ;
119 else if( Address6::af() && Address6::validString(s,&r2) )
120 m_ipv6 = std::make_unique<Address6>( s ) ;
130 throw Address::Error(
"empty string" ) ;
131 else if( Address4::af() && Address4::validString(s,&r1) )
132 m_ipv4 = std::make_unique<Address4>( s ) ;
133 else if( Address6::af() && Address6::validString(s,&r2) )
134 m_ipv6 = std::make_unique<Address6>( s ) ;
143 if( host_part.empty() )
144 throw Address::Error(
"empty string" ) ;
145 else if( AddressLocal::af() && isFamilyLocal( host_part ) )
146 m_local = std::make_unique<AddressLocal>( host_part , port_part ) ;
147 else if( Address4::af() && Address4::validStrings(host_part,port_part,&r1) )
148 m_ipv4 = std::make_unique<Address4>( host_part , port_part ) ;
149 else if( Address6::af() && Address6::validStrings(host_part,port_part,&r2) )
150 m_ipv6 = std::make_unique<Address6>( host_part , port_part ) ;
159 if( host_part.empty() )
160 throw Address::Error(
"empty string" ) ;
161 else if( AddressLocal::af() && isFamilyLocal( host_part ) )
162 m_local = std::make_unique<AddressLocal>( host_part , port ) ;
163 else if( Address4::af() && Address4::validStrings(host_part,
"0",&r1) && Address4::validPort(port) )
164 m_ipv4 = std::make_unique<Address4>( host_part , port ) ;
165 else if( Address6::af() && Address6::validStrings(host_part,
"0",&r2) && Address6::validPort(port) )
166 m_ipv6 = std::make_unique<Address6>( host_part , port ) ;
168 throw Address::Error( r1 , r1==r2?std::string():r2 ,
G::Str::printable(host_part) ) ;
173 if( Address4::af() && f == Address::Family::ipv4 )
174 m_ipv4 = std::make_unique<Address4>( port , loopback_overload ) ;
175 else if( Address6::af() && f == Address::Family::ipv6 )
176 m_ipv6 = std::make_unique<Address6>( port , loopback_overload ) ;
177 else if( AddressLocal::af() && f == Address::Family::local )
178 m_local = std::make_unique<AddressLocal>( port , loopback_overload ) ;
180 throw Address::BadFamily() ;
185 G_ASSERT( other.m_ipv4 || other.m_ipv6 || other.m_local ) ;
187 m_ipv4 = std::make_unique<Address4>( *other.m_ipv4 ) ;
189 m_ipv6 = std::make_unique<Address6>( *other.m_ipv6 ) ;
191 m_local = std::make_unique<AddressLocal>( *other.m_local ) ;
203 swap( m_ipv4 , other.m_ipv4 ) ;
204 swap( m_ipv6 , other.m_ipv6 ) ;
205 swap( m_local , other.m_local ) ;
224 return { s , not_local } ;
229 return { host_part , port } ;
234 return { host_part , port_part } ;
239 return supports( Family::local ) && !s.empty() && s[0] ==
'/' ;
244 return { Family::ipv4 , 0U } ;
249 return { f , port , 1 } ;
254 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
255 if( m_ipv4 ) m_ipv4->setPort( port ) ;
256 if( m_ipv6 ) m_ipv6->setPort( port ) ;
257 if( m_local ) m_local->setPort( port ) ;
263 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
264 if( m_ipv4 ) m_ipv4->setZone( ipv6_zone ) ;
265 if( m_ipv6 ) m_ipv6->setZone( ipv6_zone ) ;
266 if( m_local ) m_local->setZone( ipv6_zone ) ;
272 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
273 if( m_ipv4 ) m_ipv4->setScopeId( ipv6_scope_id ) ;
274 if( m_ipv6 ) m_ipv6->setScopeId( ipv6_scope_id ) ;
275 if( m_local ) m_local->setScopeId( ipv6_scope_id ) ;
281 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
282 if( m_ipv4 )
return m_ipv4->bits() ;
283 if( m_ipv6 )
return m_ipv6->bits() ;
284 if( m_local )
return m_local->bits() ;
290 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
292 ( m_ipv4 && m_ipv4->isLoopback() ) ||
293 ( m_ipv6 && m_ipv6->isLoopback() ) ||
294 ( m_local && m_local->isLoopback() ) ;
299 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
301 ( m_ipv4 && m_ipv4->isLocal(reason) ) ||
302 ( m_ipv6 && m_ipv6->isLocal(reason) ) ||
303 ( m_local && m_local->isLocal(reason) ) ;
308 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
310 ( m_ipv4 && m_ipv4->isLinkLocal() ) ||
311 ( m_ipv6 && m_ipv6->isLinkLocal() ) ||
312 ( m_local && m_local->isLinkLocal() ) ;
317 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
319 ( m_ipv4 && m_ipv4->isUniqueLocal() ) ||
320 ( m_ipv6 && m_ipv6->isUniqueLocal() ) ||
321 ( m_local && m_local->isUniqueLocal() ) ;
326 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
328 ( m_ipv4 && m_ipv4->isAny() ) ||
329 ( m_ipv6 && m_ipv6->isAny() ) ||
330 ( m_local && m_local->isAny() ) ;
345 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
347 ( m_ipv4 && other.m_ipv4 && m_ipv4->same(*other.m_ipv4,ipv6_compare_with_scope) ) ||
348 ( m_ipv6 && other.m_ipv6 && m_ipv6->same(*other.m_ipv6,ipv6_compare_with_scope) ) ||
349 ( m_local && other.m_local && m_local->same(*other.m_local,ipv6_compare_with_scope) ) ;
354 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
356 ( m_ipv4 && other.m_ipv4 && m_ipv4->same(*other.m_ipv4) ) ||
357 ( m_ipv6 && other.m_ipv6 && m_ipv6->same(*other.m_ipv6) ) ||
358 ( m_local && other.m_local && m_local->same(*other.m_local) ) ;
363 return !( *
this == other ) ;
368 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
370 ( m_ipv4 && other.m_ipv4 && m_ipv4->sameHostPart(*other.m_ipv4) ) ||
371 ( m_ipv6 && other.m_ipv6 && m_ipv6->sameHostPart(*other.m_ipv6) ) ||
372 ( m_local && other.m_local && m_local->sameHostPart(*other.m_local) ) ;
377 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
378 if( m_ipv4 )
return m_ipv4->displayString( ipv6_with_scope_id ) ;
379 if( m_ipv6 )
return m_ipv6->displayString( ipv6_with_scope_id ) ;
380 if( m_local )
return m_local->displayString( ipv6_with_scope_id ) ;
386 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
387 if( m_ipv4 )
return m_ipv4->hostPartString( raw ) ;
388 if( m_ipv6 )
return m_ipv6->hostPartString( raw ) ;
389 if( m_local )
return m_local->hostPartString( raw ) ;
395 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
396 if( m_ipv4 )
return m_ipv4->queryString() ;
397 if( m_ipv6 )
return m_ipv6->queryString() ;
398 if( m_local )
return m_local->queryString() ;
405 Address4::validString( s , reason_p ) ||
406 Address6::validString( s , reason_p ) ||
407 AddressLocal::validString( s , reason_p ) ;
413 Address4::validString( s , reason_p ) ||
414 Address6::validString( s , reason_p ) ;
420 Address4::validStrings( s1 , s2 , reason_p ) ||
421 Address6::validStrings( s1 , s2 , reason_p ) ||
422 AddressLocal::validStrings( s1 , s2 , reason_p ) ;
427 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
428 if( m_ipv4 )
return m_ipv4->address() ;
429 if( m_ipv6 )
return m_ipv6->address() ;
430 if( m_local )
return m_local->address() ;
436 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
437 if( m_ipv4 )
return m_ipv4->address() ;
438 if( m_ipv6 )
return m_ipv6->address() ;
439 if( m_local )
return m_local->address() ;
445 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
446 if( m_ipv4 )
return m_ipv4->length() ;
447 if( m_ipv6 )
return m_ipv6->length() ;
448 if( m_local )
return m_local->length() ;
454 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
455 if( m_ipv4 )
return m_ipv4->port() ;
456 if( m_ipv6 )
return m_ipv6->port() ;
457 if( m_local )
return m_local->port() ;
463 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
464 if( m_ipv4 )
return m_ipv4->scopeId( default_ ) ;
465 if( m_ipv6 )
return m_ipv6->scopeId( default_ ) ;
466 if( m_local )
return m_local->scopeId( default_ ) ;
472 return Address4::validPort( port ) ;
478 Address4::validData( addr , len ) ||
479 Address6::validData( addr , len ) ||
480 AddressLocal::validData( addr , len ) ;
485 if( family == Family::ipv4 )
return Address4::domain() ;
486 if( family == Family::ipv6 )
return Address6::domain() ;
487 if( family == Family::local )
return AddressLocal::domain() ;
493 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
494 if( m_ipv4 )
return Family::ipv4 ;
495 if( m_ipv6 )
return Family::ipv6 ;
496 if( m_local )
return Family::local ;
497 return Family::ipv4 ;
502 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
503 if( m_ipv4 )
return Address4::af() ;
504 if( m_ipv6 )
return Address6::af() ;
505 if( m_local )
return AddressLocal::af() ;
511 G_ASSERT( m_ipv4 || m_ipv6 || m_local ) ;
512 if( m_ipv4 )
return m_ipv4->wildcards() ;
513 if( m_ipv6 )
return m_ipv6->wildcards() ;
514 if( m_local )
return m_local->wildcards() ;
535 static_assert(
sizeof(Address4::sockaddr_type) <=
sizeof(sockaddr_storage) ,
"" ) ;
536 static_assert(
sizeof(Address6::sockaddr_type) <=
sizeof(sockaddr_storage) ,
"" ) ;
537 static_assert(
sizeof(AddressLocal::sockaddr_type) <=
sizeof(sockaddr_storage) ,
"" ) ;
539 static_assert(
alignof(Address4::sockaddr_type) <=
alignof(sockaddr_storage) ,
"" ) ;
540 static_assert(
alignof(Address6::sockaddr_type) <=
alignof(sockaddr_storage) ,
"" ) ;
541 static_assert(
alignof(AddressLocal::sockaddr_type) <=
alignof(sockaddr_storage) ,
"" ) ;
543 m_imp->n =
sizeof( sockaddr_storage ) ;
551 return reinterpret_cast<sockaddr*
>(&(m_imp->u)) ;
561 return reinterpret_cast<const sockaddr*
>(&(m_imp->u)) ;
571#if ! GCONFIG_HAVE_INET_PTON
573int GNet::inet_pton_imp(
int f ,
const char * p ,
void * result )
575 if( p ==
nullptr || result ==
nullptr )
return 0 ;
576 struct addrinfo ai_hint ;
577 std::memset( &ai_hint , 0 ,
sizeof(ai_hint) ) ;
578 ai_hint.ai_family = f ;
579 ai_hint.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV ;
580 struct addrinfo * ai_p = nullptr ;
581 int rc = getaddrinfo( p ,
nullptr , &ai_hint , &ai_p ) ;
582 bool ok = rc == 0 && ai_p != nullptr ;
583 if( ok && ai_p->ai_addr ==
nullptr ) { freeaddrinfo(ai_p) ;
return 1 ; }
586 struct sockaddr * sa_p = ai_p->ai_addr ;
587 if( ai_p->ai_family == AF_INET )
589 struct sockaddr_in sa ;
590 std::memcpy( &sa , sa_p ,
sizeof(sa) ) ;
591 std::memcpy( result , &sa.sin_addr ,
sizeof(sa.sin_addr) ) ;
593 else if( ai_p->ai_family == AF_INET6 )
595 struct sockaddr_in6 sa ;
596 std::memcpy( &sa , sa_p ,
sizeof(sa) ) ;
597 std::memcpy( result , &sa.sin6_addr ,
sizeof(sa.sin6_addr) ) ;
603 freeaddrinfo( ai_p ) ;
609#if ! GCONFIG_HAVE_INET_NTOP
611const char * GNet::inet_ntop_imp(
int f ,
void * ap ,
char * buffer , std::size_t n )
616 std::ostringstream ss ;
618 std::memcpy( &a , ap ,
sizeof(a) ) ;
619 ss << inet_ntoa( a ) ;
622 else if( f == AF_INET6 )
625 std::memcpy( &a , ap ,
sizeof(a) ) ;
626 std::ostringstream ss ;
627 const char * sep =
":" ;
628 const char * hexmap =
"0123456789abcdef" ;
629 for(
int i = 0 ; i < 16 ; i++ , sep = *sep ?
"" :
":" )
631 unsigned int n =
static_cast<unsigned int>(a.s6_addr[i]) % 256U ;
632 ss << sep << hexmap[(n>>4U)%16U] << hexmap[(n&15U)%16U] ;
637 for( std::string::size_type pos = s.find(
":0") ; pos != std::string::npos ; pos = s.find(
":0",pos) )
640 while( s.at(pos) ==
'0' && s.at(pos+1U) !=
':' )
641 s.erase( pos , 1U ) ;
644 std::string run =
":0:0:0:0:0:0:0:0:" ;
645 while( run.length() >= 5U )
647 std::string::size_type pos = s.find( run ) ;
648 if( pos != std::string::npos )
650 std::string::size_type r = 2U ;
651 if( pos == 0U ) r++ ;
652 if( (pos + run.length()) == s.length() ) r++ ;
653 s.replace( pos , run.length() , std::string(
"::::").substr(0U,r) ) ;
656 run.erase( 0U , 2U ) ;
659 G_ASSERT( s.length() > 2U ) ;
661 s.erase( s.length()-1U , 1U ) ;
668 if( n <= s.length() )
return nullptr ;
669 std::strncpy( buffer , s.c_str() , n ) ;
A pimple-pattern implementation class used by GNet::AddressStorage.
A helper class for calling accept(), getsockname() and getpeername() and hiding the definition of soc...
sockaddr * p1()
Returns the sockaddr pointer for accept()/getsockname()/getpeername() to write into.
const sockaddr * p() const
Returns the pointer, typically set via p1().
socklen_t * p2()
Returns the length pointer for accept()/getsockname()/getpeername() to write into.
AddressStorage()
Default constructor, with n() reflecting the size of the largest supported address type.
~AddressStorage()
Destructor.
socklen_t n() const
Returns the length, typically modified via p2().
The GNet::Address class encapsulates a TCP/UDP transport address.
bool setZone(const std::string &)
Sets the zone.
Address & setScopeId(unsigned long)
Sets the scope-id.
bool is4() const
Returns true if family() is ipv4.
Family family() const
Returns the address family enumeration.
Address(const Address &)
Copy constructor.
int af() const
Returns the address family number such as AF_INET or AFINET6.
bool operator!=(const Address &) const
Comparison operator.
bool isLinkLocal() const
Returns true if this is a link-local address.
bool operator==(const Address &) const
Comparison operator.
std::string queryString() const
Returns a string that can be used as a prefix for rDNS or DNSBL queries.
G::StringArray wildcards() const
Returns an ordered list of wildcard strings that match this address.
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 ...
static bool validData(const sockaddr *, socklen_t len)
Returns true if the sockaddr data is valid.
std::string hostPartString(bool raw=false) const
Returns a string which represents the network address.
static bool supports(Family)
Returns true if the implementation supports the given address family.
static Address loopback(Family, unsigned int port=0U)
Returns a loopback address.
static bool validPort(unsigned int n)
Returns true if the port number is within the valid range.
bool isUniqueLocal() const
Returns true if this is a locally administered address.
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.
void swap(Address &other) noexcept
Swaps this with other.
socklen_t length() const
Returns the size of the sockaddr address. See address().
bool isLocal(std::string &reason) const
Returns true if this seems to be a 'local' address, ie.
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number.
Address & operator=(const Address &)
Assignment operator.
bool isAny() const
Returns true if this is the address family's 'any' address.
bool is6() const
Returns true if family() is ipv6.
static Address parse(const std::string &display_string)
Factory function for any address family.
static bool validString(const std::string &display_string, std::string *reason=nullptr)
Returns true if the transport-address display string is valid.
bool sameHostPart(const Address &other) const
Returns true if the two addresses have the same host part (ie.
unsigned int bits() const
Returns the number of leading bits set, relevant only to netmask addresses.
std::string displayString(bool with_scope_id=false) const
Returns a string which represents the transport address.
unsigned int port() const
Returns port part of the address.
bool isLoopback() const
Returns true if this is a loopback address.
const sockaddr * address() const
Returns the sockaddr address.
unsigned long scopeId(unsigned long default_=0UL) const
Returns the scope-id.
Address & setPort(unsigned int port)
Sets the port number.
static int domain(Family)
Returns the address 'domain' for the given family, eg.
bool same(const Address &, bool ipv6_compare_with_scope) const
Comparison function.
static std::string printable(const std::string &in, char escape='\\')
Returns a printable representation of the given input string, using chacter code ranges 0x20 to 0x7e ...
std::vector< std::string > StringArray
A std::vector of std::strings.
Overload discriminator for Address::supports()
Overload discriminator for Address::parse()