28 m_host(head(sockless(spec))) ,
29 m_service(tail(sockless(spec))) ,
30 m_address_valid(false) ,
31 m_address(
Address::defaultAddress()) ,
36 m_using_socks = socksified( spec , m_socks_far_host , m_socks_far_port ) ;
38 throw InvalidFormat( spec ) ;
39 G_DEBUG(
"GNet::Location::ctor: unresolved location [" <<
displayString() <<
"]" << (m_using_socks?
" (using socks)":
"") ) ;
44 m_service(tail(spec)) ,
45 m_address_valid(false) ,
46 m_address(
Address::defaultAddress()) ,
51 G_DEBUG(
"GNet::Location::ctor: unresolved location [" <<
displayString() <<
"]" ) ;
53 throw InvalidFormat( spec ) ;
57 m_host(head(socks_server)) ,
58 m_service(tail(socks_server)) ,
59 m_address_valid(false) ,
60 m_address(Address::defaultAddress()) ,
64 m_socks_far_host(head(far_server)) ,
65 m_socks_far_port(tail(far_server))
67 if( m_socks_far_host.empty() || m_socks_far_port.empty() )
68 throw InvalidFormat() ;
70 throw InvalidFormat(
"invalid port number: [" + m_socks_far_port +
"]" ) ;
72 throw InvalidFormat( socks_server ) ;
73 G_DEBUG(
"GNet::Location::ctor: unresolved location [" <<
displayString() <<
"]" <<
" (using socks)" ) ;
78 return { spec , family , 1 } ;
84 return { socks_server , far_server , AF_UNSPEC } ;
88std::string GNet::Location::sockless(
const std::string & s )
94bool GNet::Location::socksified(
const std::string & s , std::string & far_host_out , std::string & far_port_out )
96 std::string::size_type pos = s.find(
'@') ;
97 if( pos != std::string::npos )
104 return pos != std::string::npos ;
107std::string GNet::Location::head(
const std::string & s )
109 std::size_t pos = s.rfind(
':' ) ;
110 std::string h = ( pos == std::string::npos && !s.empty() && s[0] ==
'/' ) ? s :
G::Str::head( s , pos ) ;
111 if( h.size() > 1U && h.at(0U) ==
'[' && h.at(h.size()-1U) ==
']' )
112 h = h.substr( 1U , h.size()-2U ) ;
116std::string GNet::Location::tail(
const std::string & s )
139 std::string address_string =
G::Str::join(
":" , m_host , m_service ) ;
143 update( address , std::string() ) ;
150 return m_address_valid ;
160 if( !update(address,name,std::nothrow) )
161 throw InvalidFamily() ;
167 address.
family() == Address::Family::ipv4 ||
168 address.
family() == Address::Family::ipv6 ||
169 address.
family() == Address::Family::local ;
171 if( !valid_family || ( m_family != AF_UNSPEC && address.
af() != m_family ) )
174 m_address = address ;
175 m_family = address.
af() ;
176 m_address_valid = true ;
177 m_canonical_name = name ;
179 G_DEBUG(
"GNet::Location::ctor: resolved location [" << displayString() <<
"]" ) ;
185 return m_canonical_name ;
192 return address().displayString() ;
194 else if( m_host.find(
'/') == 0U )
200 const char * ipvx = m_family == AF_UNSPEC ?
"ip" : ( m_family == AF_INET ?
"ipv4" :
"ipv6" ) ;
201 return m_host +
"/" + m_service +
"/" + ipvx ;
208 return m_update_time ;
214 return m_using_socks ;
219 G_ASSERT( m_socks_far_port.empty() ||
G::Str::isUInt(m_socks_far_port) ) ;
220 return m_socks_far_port.empty() ? 0U :
G::Str::toUInt(m_socks_far_port) ;
225 return m_socks_far_host ;
The GNet::Address class encapsulates a TCP/UDP transport address.
int af() const noexcept
Returns the address family number such as AF_INET or AFINET6.
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.
Family family() const noexcept
Returns the address family enumeration.
A class that represents the remote target for out-going client connections.
int family() const
Returns the preferred name resolution address family as passed to the constructor.
bool resolved() const
Returns true after update() has been called or resolveTrivially() succeeded.
bool resolveTrivially()
If host() and service() are already in address format then do a trivial update() so that the location...
std::string name() const
Returns the remote canonical name.
std::string displayString() const
Returns a string representation for logging and debug.
std::string socksFarHost() const
Returns the port for the socks far server.
G::SystemTime updateTime() const
Returns the time of the last update() or zero if never update()d.
bool socks() const
Returns true if a socks location.
void update(const Address &address, const std::string &canonical_name)
Updates the address and canonical name, typically after doing a name lookup on host() and service().
std::string service() const
Returns the remote service name derived from the constructor parameter.
unsigned int socksFarPort() const
Returns the port number for the socks far server.
Address address() const
Returns the remote address.
std::string host() const
Returns the remote host name derived from the constructor parameter.
Location(const std::string &spec, int family=AF_UNSPEC)
Constructor taking a formatted "host:service" string.
static Location nosocks(const std::string &spec, int family=AF_UNSPEC)
Factory function for a remote location but not allowing the extended syntax for socks.
static unsigned int toUInt(string_view s)
Converts string 's' to an unsigned int.
static std::string join(string_view sep, const StringArray &strings)
Concatenates an array of strings with separators.
static bool isUInt(string_view s) noexcept
Returns true if the string can be converted into an unsigned integer without throwing an exception.
static std::string tail(string_view in, std::size_t pos, string_view default_={})
Returns the last part of the string after the given position.
static std::string head(string_view in, std::size_t pos, string_view default_={})
Returns the first part of the string up to just before the given position.
Represents a unix-epoch time with microsecond resolution.
static SystemTime now()
Factory function for the current time.