30 static bool is4(
const sockaddr * p )
32 return p && p->sa_family == GNet::Address4::family() ;
34 static bool is4(
const std::string & s )
37 return GNet::Address4::validString(s,&r) ;
39 static bool is4(
const std::string & s ,
unsigned int )
42 return GNet::Address4::validStrings(s,
"0",&r) ;
53 return Address( Family::ipv4() , 0U ) ;
57 m_4imp( f==Family::ipv4() ? new Address4(port) : nullptr ) ,
58 m_6imp( f!=Family::ipv4() ? new Address6(port) : nullptr )
63 m_4imp( is4(storage.p()) ? new Address4(storage.p(),storage.n()) : nullptr ) ,
64 m_6imp( !is4(storage.p()) ? new Address6(storage.p(),storage.n()) : nullptr )
69 m_4imp( is4(addr) ? new Address4(addr,len) : nullptr ) ,
70 m_6imp( !is4(addr) ? new Address6(addr,len) : nullptr )
75 m_4imp( is4(s) ? new Address4(s) : nullptr ) ,
76 m_6imp( !is4(s) ? new Address6(s) : nullptr )
81 m_4imp( is4(s,port) ? new Address4(s,port) : nullptr ) ,
82 m_6imp( !is4(s,port) ? new Address6(s,port) : nullptr )
87 m_4imp( other.m_4imp ? new Address4(*other.m_4imp) : nullptr ) ,
88 m_6imp( other.m_6imp ? new Address6(*other.m_6imp) : nullptr )
93 m_4imp( f==Family::ipv4() ? new Address4(port,loopback_overload) : nullptr ) ,
94 m_6imp( f!=Family::ipv4() ? new Address6(port,loopback_overload) : nullptr )
100 return Address( f , port , 1 ) ;
105 Address temp( addr ) ;
106 std::swap( m_4imp , temp.m_4imp ) ;
107 std::swap( m_6imp , temp.m_6imp ) ;
118 m_4imp ? m_4imp->setPort(port) : m_6imp->setPort(port) ;
124 ( m_4imp && m_4imp->isLoopback() ) ||
125 ( m_6imp && m_6imp->isLoopback() ) ;
131 ( m_4imp && m_4imp->isLocal(reason) ) ||
132 ( m_6imp && m_6imp->isLocal(reason) ) ;
138 ( m_4imp && other.m_4imp && m_4imp->same(*other.m_4imp) ) ||
139 ( m_6imp && other.m_6imp && m_6imp->same(*other.m_6imp) ) ;
144 return !( *
this == other ) ;
150 ( m_4imp && other.m_4imp && m_4imp->sameHostPart(*other.m_4imp) ) ||
151 ( m_6imp && other.m_6imp && m_6imp->sameHostPart(*other.m_6imp) ) ;
156 return m_4imp ? m_4imp->displayString() : m_6imp->displayString() ;
161 return m_4imp ? m_4imp->hostPartString() : m_6imp->hostPartString() ;
166 return Address4::validString( s , reason_p ) || Address6::validString( s , reason_p ) ;
171 return Address4::validStrings( s1 , s2 , reason_p ) || Address6::validStrings( s1 , s2 , reason_p ) ;
176 return m_4imp ? m_4imp->address() : m_6imp->address() ;
181 return m_4imp ? m_4imp->address() : m_6imp->address() ;
186 return m_4imp ? Address4::length() : Address6::length() ;
191 return m_4imp ? m_4imp->port() : m_6imp->port() ;
196 return m_4imp ? default_ : m_6imp->scopeId() ;
201 return Address4::validPort( port ) ;
206 return Address4::validData( addr , len ) || Address6::validData( addr , len ) ;
211 return m_4imp ? Address4::domain() : Address6::domain() ;
216 return m_4imp ? Family::ipv4() : Family::ipv6() ;
221 return m_4imp ? m_4imp->wildcards() : m_6imp->wildcards() ;
232 Address6::union_type u ;
239 m_imp(new AddressStorageImp)
241 m_imp->n =
sizeof(Address6::union_type) ;
251 return &(m_imp->u.general) ;
261 return &m_imp->u.general ;
273 int GNet::inet_pton_imp(
int f ,
const char * p ,
void * result )
275 if( p ==
nullptr || result ==
nullptr )
return 0 ;
276 struct addrinfo ai_hint ;
277 std::memset( &ai_hint , 0 ,
sizeof(ai_hint) ) ;
278 ai_hint.ai_family = f ;
279 ai_hint.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV ;
280 struct addrinfo * ai_p = nullptr ;
281 int rc = getaddrinfo( p ,
nullptr , &ai_hint , &ai_p ) ;
282 bool ok = rc == 0 && ai_p != nullptr ;
283 if( ok && ai_p->ai_addr ==
nullptr ) { freeaddrinfo(ai_p) ;
return 1 ; }
286 struct sockaddr * sa_p = ai_p->ai_addr ;
287 if( ai_p->ai_family == AF_INET )
289 struct sockaddr_in sa = *
reinterpret_cast<struct sockaddr_in*
>(sa_p) ;
290 *
reinterpret_cast<struct in_addr*
>(result) = sa.sin_addr ;
292 else if( ai_p->ai_family == AF_INET6 )
294 struct sockaddr_in6 sa = *
reinterpret_cast<struct sockaddr_in6*
>(sa_p) ;
295 *
reinterpret_cast<struct in6_addr*
>(result) = sa.sin6_addr ;
299 freeaddrinfo( ai_p ) ;
304 #if ! GCONFIG_HAVE_INET_NTOP
306 const char * GNet::inet_ntop_imp(
int f ,
void * ap ,
char * buffer ,
size_t n )
311 std::ostringstream ss ;
312 struct in_addr a = *
reinterpret_cast<struct in_addr*
>(ap) ;
313 ss << inet_ntoa( a ) ;
316 else if( f == AF_INET6 )
318 struct in6_addr a = *
reinterpret_cast<struct in6_addr*
>(ap) ;
319 std::ostringstream ss ;
320 const char * sep =
":" ;
321 const char * hexmap =
"0123456789abcdef" ;
322 for(
int i = 0 ; i < 16 ; i++ , sep = *sep ?
"" :
":" )
324 unsigned int n =
static_cast<unsigned int>(a.s6_addr[i]) % 256U ;
325 ss << sep << hexmap[(n>>4U)%16U] << hexmap[(n&15U)%16U] ;
329 for( std::string::size_type pos = s.find(
":0") ; pos != std::string::npos ; pos = s.find(
":0",pos) )
331 if( s.find(
":0:",pos) == std::string::npos )
332 s.erase( pos+1U , 1U ) ;
336 std::string run =
":0:0:0:0:0:0:0:0:" ;
337 while( run.length() >= 3U )
339 std::string::size_type pos = s.find( run ) ;
340 if( pos != std::string::npos )
342 std::string::size_type r = 2U ;
343 if( pos == 0U ) r++ ;
344 if( (pos + run.length()) == s.length() ) r++ ;
345 s.replace( pos , run.length() , std::string(
"::::").substr(0U,r) ) ;
348 run.erase( 0U , 2U ) ;
351 s.erase( s.length()-1U , 1U ) ;
357 if( n <= s.length() )
return nullptr ;
358 std::strncpy( buffer , s.c_str() , n ) ;
static Address loopback(Family, unsigned int port=0U)
Returns a loopback address.
Family family() const
Returns the address family.
static bool validData(const sockaddr *, socklen_t len)
Returns true if the sockaddr data is valid.
The GNet::Address class encapsulates a TCP/UDP transport address.
bool isLoopback() const
Returns true if this is a loopback address.
static bool validStrings(const std::string &ip, const std::string &port_string, std::string *reason=nullptr)
Returns true if the combined ip address string and port string is valid.
std::vector< std::string > StringArray
A std::vector of std::strings.
socklen_t * p2()
Returns the length pointer for accept()/getsockname()/getpeername() to write into.
sockaddr * p1()
Returns the sockaddr pointer for accept()/getsockname()/getpeername() to write into.
A pimple-pattern implementation class used by GNet::AddressStorage.
const sockaddr * address() const
Returns the sockaddr address.
bool sameHostPart(const Address &other) const
Returns true if the two addresses have the same host part (ie.
unsigned int port() const
Returns port part of the address.
bool operator==(const Address &) const
Comparison operator.
const sockaddr * p() const
Returns the pointer.
AddressStorage()
Default constructor.
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number.
G::StringArray wildcards() const
Returns an ordered list of wildcard strings that match this address.
socklen_t length() const
Returns the size of the sockaddr address. See address().
std::string hostPartString() const
Returns a string which represents the network address for debugging and diagnostics purposes...
unsigned long scopeId(unsigned long default_=0UL) const
Returns the scope-id.
static bool validString(const std::string &display_string, std::string *reason=nullptr)
Returns true if the display string is valid.
int domain() const
Returns the address 'domain', eg. PF_INET.
~AddressStorage()
Destructor.
static bool validPort(unsigned int n)
Returns true if the port number is within the valid range.
A type-safe enumerator for IP address family.
This file is formatted for side-by-side comparison with gaddress4.h.
bool isLocal(std::string &reason) const
Returns true if this seems to be a local address.
void operator=(const Address &addr)
Assignment operator.
Address(const Address &)
Copy constructor.
This file is formatted for side-by-side comparison with gaddress6.h.
void setPort(unsigned int port)
Sets the port number.
socklen_t n() const
Returns the length.
static bool supports(Family)
Returns true if the implementation supports the given address family.
bool operator!=(const Address &) const
Comparison operator.
std::string displayString() const
Returns a string which represents the transport address for debugging and diagnostics purposes...