35 m_numeric_service(!service.empty() &&
G::Str::isNumeric(service)) ,
36 m_host(encode(host,config.raw)) ,
37 m_host_p(m_host.c_str()) ,
39 m_service_p(m_service.c_str()) ,
42 std::memset( &m_ai_hint , 0 ,
sizeof(m_ai_hint) ) ;
43 m_ai_hint.ai_family = family ;
44 m_ai_hint.ai_socktype = config.datagram ? SOCK_DGRAM : SOCK_STREAM ;
45 m_ai_hint.ai_flags = 0 ;
46 if( config.with_canonical_name ) m_ai_hint.ai_flags |= AI_CANONNAME ;
47 if( family == AF_UNSPEC ) m_ai_hint.ai_flags |= AI_ADDRCONFIG ;
48 if( m_numeric_service ) m_ai_hint.ai_flags |= AI_NUMERICSERV ;
49 #if GCONFIG_HAVE_GAI_IDN
50 if( config.idn_flag ) m_ai_hint.ai_flags |= AI_IDN ;
57 GetAddrInfo::freeaddrinfo( m_ai ) ;
60std::string GNet::ResolverFuture::encode(
const std::string & host ,
bool raw )
73 if( m_config.test_slow ) sleep( 10 ) ;
74 m_rc = GetAddrInfo::getaddrinfo( m_host_p , m_service_p , &m_ai_hint , &m_ai ) ;
78std::string GNet::ResolverFuture::failure()
const
80 std::stringstream ss ;
81 if( m_numeric_service )
82 ss <<
"no such " << ipvx() <<
"host: \"" << m_host <<
"\"" ;
84 ss <<
"no such " << ipvx() <<
"host or service: \"" << m_host <<
":" << m_service <<
"\"" ;
85 const char * reason = GetAddrInfo::gai_strerror( m_rc ) ;
86 if( reason && *reason )
91std::string GNet::ResolverFuture::ipvx()
const
93 if( m_family == AF_UNSPEC )
return {} ;
94 if( m_family == AF_INET )
return "ipv4 " ;
98bool GNet::ResolverFuture::failed()
const
100 return m_rc != 0 || m_ai ==
nullptr || m_ai->ai_addr ==
nullptr || m_ai->ai_addrlen == 0 ;
103std::string GNet::ResolverFuture::none()
const
105 return "no usable addresses returned for \"" + m_host +
"\"" ;
108bool GNet::ResolverFuture::fetch( Result & result )
const
111 for(
const struct addrinfo * p = m_ai ; p ; p = p->ai_next )
113 socklen_t addrlen =
static_cast<socklen_t
>(p->ai_addrlen) ;
116 result.address = Address( p->ai_addr , addrlen ) ;
117 if( m_config.with_canonical_name && p->ai_canonname )
118 result.canonicalName.assign( p->ai_canonname ) ;
125bool GNet::ResolverFuture::fetch( List & list )
const
128 bool got_one = false ;
129 for(
const struct addrinfo * p = m_ai ; p ; p = p->ai_next )
131 socklen_t addrlen =
static_cast<socklen_t
>(p->ai_addrlen) ;
134 list.emplace_back( p->ai_addr , addrlen ) ;
144 m_reason = failure() ;
145 else if( !fetch(list) )
153 m_reason = failure() ;
154 else if( !fetch(result) )
161 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...
Result get()
Returns the resolved address after run() has completed.
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().
ResolverFuture(const std::string &host, const std::string &service, int family, const Resolver::Config &)
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 lower(std::string_view)
Returns a copy of 's' in which all seven-bit upper-case characters have been replaced by lower-case c...
static bool isPrintableAscii(std::string_view s) noexcept
Returns true if every character is between 0x20 and 0x7e inclusive.
static std::string trimmed(const std::string &s, std::string_view ws)
Returns a trim()med version of s.
std::string encode(std::string_view domain)
Returns the given domain with A-lables.
bool valid(std::string_view domain)
Returns true if the given domain is valid with U-labels and/or A-labels.
Result structure for GNet::ResolverFuture::get().
A configuration structure for GNet::Resolver.