31 bool dgram ,
bool for_async_hint ) :
32 m_numeric_service(!service.empty() &&
G::Str::isNumeric(service)) ,
33 m_socktype(dgram?SOCK_DGRAM:SOCK_STREAM) ,
35 m_host_p(m_host.c_str()) ,
37 m_service_p(m_service.c_str()) ,
39 m_test_mode(for_async_hint&&
G::Test::enabled(
"getaddrinfo-slow")) ,
43 std::memset( &m_ai_hint , 0 ,
sizeof(m_ai_hint) ) ;
44 m_ai_hint.ai_flags = AI_CANONNAME |
45 ( family == AF_UNSPEC ? AI_ADDRCONFIG : 0 ) |
46 ( m_numeric_service ? AI_NUMERICSERV : 0 ) ;
47 m_ai_hint.ai_family = family ;
48 m_ai_hint.ai_socktype = m_socktype ;
54 ::freeaddrinfo( m_ai ) ;
60 if( m_test_mode ) sleep( 10 ) ;
61 m_rc = ::getaddrinfo( m_host_p , m_service_p , &m_ai_hint , &m_ai ) ;
65std::string GNet::ResolverFuture::failure()
const
67 std::stringstream ss ;
68 if( m_numeric_service )
69 ss <<
"no such " << ipvx() <<
"host: \"" << m_host <<
"\"" ;
71 ss <<
"no such " << ipvx() <<
"host or service: \"" << m_host <<
":" << m_service <<
"\"" ;
72 const char * reason = gai_strerror( m_rc ) ;
73 if( reason && *reason )
78std::string GNet::ResolverFuture::ipvx()
const
80 if( m_family == AF_UNSPEC )
return std::string() ;
81 if( m_family == AF_INET )
return "ipv4 " ;
85bool GNet::ResolverFuture::failed()
const
87 return m_rc != 0 || m_ai ==
nullptr || m_ai->ai_addr ==
nullptr || m_ai->ai_addrlen == 0 ;
90std::string GNet::ResolverFuture::none()
const
92 return "no usable addresses returned for \"" + m_host +
"\"" ;
95bool GNet::ResolverFuture::fetch( Pair & pair )
const
98 for(
const struct addrinfo * p = m_ai ; p ; p = p->ai_next )
100 socklen_t addrlen =
static_cast<socklen_t
>(p->ai_addrlen) ;
103 Address address( p->ai_addr , addrlen ) ;
104 std::string name( p->ai_canonname ? p->ai_canonname :
"" ) ;
105 pair = std::make_pair( address , name ) ;
112bool GNet::ResolverFuture::fetch( List & list )
const
115 bool got_one = false ;
116 for(
const struct addrinfo * p = m_ai ; p ; p = p->ai_next )
118 socklen_t addrlen =
static_cast<socklen_t
>(p->ai_addrlen) ;
121 list.push_back( Address( p->ai_addr , addrlen ) ) ;
131 m_reason = failure() ;
132 else if( !fetch(list) )
140 m_reason = failure() ;
141 else if( !fetch(result) )
148 return !m_reason.empty() ;
static bool validData(const sockaddr *, socklen_t len)
Returns true if the sockaddr data is valid.
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number.
A 'future' shared-state class for asynchronous name resolution that holds parameters and results of a...
bool error() const
Returns true if name resolution failed or no suitable address was returned.
std::string reason() const
Returns the reason for the error().
Pair get()
Returns the resolved address/name pair after run() has completed.
ResolverFuture(const std::string &host, const std::string &service, int family, bool dgram, bool for_async_hint=false)
Constructor for resolving the given host and service names.
ResolverFuture & run() noexcept
Does the synchronous name resolution and stores the result.
~ResolverFuture()
Destructor.
static std::string trimmed(const std::string &s, string_view ws)
Returns a trim()med version of s.
static std::string lower(const std::string &s)
Returns a copy of 's' in which all Latin-1 upper-case characters have been replaced by lower-case cha...