E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

glocation.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // glocation.cpp
19 //
20
21 #include "gdef.h"
22 #include "gstr.h"
23 #include "glocation.h"
24 #include "gresolver.h"
25 #include "gassert.h"
26
27 namespace
28 {
29 const char * host_service_separators = ":/" ;
30 }
31
32 GNet::Location::Location( const std::string & host , const std::string & service , int family ) :
33 m_host(host) ,
34 m_service(service) ,
35 m_address_valid(false) ,
36 m_address(Address::defaultAddress()) ,
37 m_family(family) ,
38 m_dgram(false) ,
39 m_update_time(0U) ,
40 m_socks(false) ,
41 m_socks_far_port(0U)
42 {
43 G_DEBUG( "GNet::Location::ctor: unresolved location [" << displayString() << "]" ) ;
44 }
45
46 GNet::Location::Location( const std::string & socks_host , const std::string & socks_service ,
47 const std::string & far_host , const std::string & far_service , int family ) :
48 m_host(socks_host) ,
49 m_service(socks_service) ,
50 m_address_valid(false) ,
51 m_address(Address::defaultAddress()) ,
52 m_family(family) ,
53 m_dgram(false) ,
54 m_update_time(0U) ,
55 m_socks(!far_host.empty()) ,
56 m_socks_far_host(far_host) ,
57 m_socks_far_port(0U)
58 {
59 if( far_host.empty() != far_service.empty() )
60 throw InvalidFormat() ;
61 if( m_socks && !G::Str::isUInt(far_service) )
62 throw InvalidFormat( "invalid port number: [" + far_service + "]" ) ;
63 if( m_socks )
64 m_socks_far_port = G::Str::toUInt( far_service ) ;
65 G_DEBUG( "GNet::Location::ctor: unresolved location [" << displayString() << "]" << (m_socks?" (using socks)":"") ) ;
66 }
67
68 GNet::Location::Location( const std::string & location_string , int family ) :
69 m_host(head(sockless(location_string))) ,
70 m_service(tail(sockless(location_string))) ,
71 m_address_valid(false) ,
72 m_address(Address::defaultAddress()) ,
73 m_family(family) ,
74 m_dgram(false) ,
75 m_update_time(0U) ,
76 m_socks(false) ,
77 m_socks_far_port(0U)
78 {
79 m_socks = socksified( location_string , m_socks_far_host , m_socks_far_port ) ;
80 if( m_host.empty() || m_service.empty() )
81 throw InvalidFormat( location_string ) ;
82 G_DEBUG( "GNet::Location::ctor: unresolved location [" << displayString() << "]" << (m_socks?" (using socks)":"") ) ;
83 }
84
85 std::string GNet::Location::sockless( const std::string & s )
86 {
87 // "far-host:far-port@sockserver-host:sockserver-port"
88 return G::Str::tail( s , s.find('@') , s ) ;
89 }
90
91 bool GNet::Location::socksified( const std::string & s , std::string & far_host , unsigned int & far_port )
92 {
93 std::string::size_type pos = s.find('@') ;
94 if( pos != std::string::npos )
95 {
96 std::string ss = G::Str::head( s , pos ) ;
97 far_host = G::Str::head( ss , ss.find_last_of(host_service_separators) ) ;
98 far_port = G::Str::toUInt( G::Str::tail( ss , ss.find_last_of(host_service_separators) ) ) ;
99 }
100 return pos != std::string::npos ;
101 }
102
103 std::string GNet::Location::head( const std::string & s )
104 {
105 std::string result = G::Str::head( s , s.find_last_of(host_service_separators) ) ;
106 if( result.size() > 1U && result.at(0U) == '[' && result.at(result.size()-1U) == ']' )
107 result = result.substr( 1U , result.size()-2U ) ;
108 return result ;
109 }
110
111 std::string GNet::Location::tail( const std::string & s )
112 {
113 return G::Str::tail( s , s.find_last_of(host_service_separators) ) ;
114 }
115
116 std::string GNet::Location::host() const
117 {
118 return m_host ;
119 }
120
121 std::string GNet::Location::service() const
122 {
123 return m_service ;
124 }
125
126 int GNet::Location::family() const
127 {
128 return m_family ;
129 }
130
131 bool GNet::Location::dgram() const
132 {
133 return m_dgram ;
134 }
135
136 void GNet::Location::resolveTrivially()
137 {
138 std::string reason ;
139 if( !resolved() && Address::validStrings(m_host,m_service,&reason) )
140 update( Address(m_host,G::Str::toUInt(m_service)) , std::string() ) ;
141 }
142
143 bool GNet::Location::resolved() const
144 {
145 return m_address_valid ;
146 }
147
148 GNet::Address GNet::Location::address() const
149 {
150 return m_address ;
151 }
152
153 void GNet::Location::update( const Address & address , const std::string & name )
154 {
155 G_ASSERT( m_family == AF_UNSPEC || address.domain() == m_family ) ;
156 m_address = address ;
157 m_family = address.domain() ; // not family()
158 m_address_valid = true ;
159 m_canonical_name = name ;
160 m_update_time = G::DateTime::now() ;
161 G_DEBUG( "GNet::Location::ctor: resolved location [" << displayString() << "]" ) ;
162 }
163
164 std::string GNet::Location::name() const
165 {
166 return m_canonical_name ;
167 }
168
169 std::string GNet::Location::displayString() const
170 {
171 const char * ipvx = m_family == AF_UNSPEC ? "ip" : ( m_family == AF_INET ? "ipv4" : "ipv6" ) ;
172 return resolved() ? address().displayString() : (m_host+"/"+m_service+"/"+ipvx) ;
173 }
174
175 G::EpochTime GNet::Location::updateTime() const
176 {
177 return m_update_time ;
178 }
179
180 bool GNet::Location::socks() const
181 {
182 return m_socks ;
183 }
184
185 unsigned int GNet::Location::socksFarPort() const
186 {
187 return m_socks_far_port ;
188 }
189
190 std::string GNet::Location::socksFarHost() const
191 {
192 return m_socks_far_host ;
193 }
194
195 /// \file glocation.cpp
G::EpochTime
A subsecond-resolution timestamp based on a time_t.
Definition: gdatetime.h:39
G::Str::tail
static std::string tail(const std::string &in, size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
Definition: gstr.cpp:1102
G::Str::head
static std::string head(const std::string &in, size_type pos, const std::string &default_=std::string())
Returns the first part of the string up to just before the given position.
Definition: gstr.cpp:1088
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:54
GNet::Location::socks
bool socks() const
Returns true if a socks location.
Definition: glocation.cpp:180
GNet::Address::validStrings
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.
Definition: gaddress_ipv4.cpp:144
GNet::Location::displayString
std::string displayString() const
Returns a string representation for logging and debug.
Definition: glocation.cpp:169
glocation.h
G::DateTime::now
static EpochTime now()
Returns the current epoch time.
Definition: gdatetime_unix.cpp:26
G::Str::toUInt
static unsigned int toUInt(const std::string &s)
Converts string 's' to an unsigned int.
Definition: gstr.cpp:488
GNet::Location::dgram
bool dgram() const
Returns true if the name resolution should be specifically for datagram sockets.
Definition: glocation.cpp:131
gstr.h
gassert.h
GNet::Location::name
std::string name() const
Returns the remote canonical name.
Definition: glocation.cpp:164
GNet::Location::update
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()...
Definition: glocation.cpp:153
GNet::Location::address
Address address() const
Returns the remote address.
Definition: glocation.cpp:148
GNet::Location::socksFarHost
std::string socksFarHost() const
Returns the port for the socks far server.
Definition: glocation.cpp:190
GNet::Location::resolved
bool resolved() const
Returns true after update() has been called.
Definition: glocation.cpp:143
GNet::Address::domain
int domain() const
Returns the address 'domain', eg. PF_INET.
Definition: gaddress_ipv4.cpp:184
GNet::Location::service
std::string service() const
Returns the remote service name, as passed in to the constructor.
Definition: glocation.cpp:121
GNet::Location::socksFarPort
unsigned int socksFarPort() const
Returns the port number for the socks far server.
Definition: glocation.cpp:185
GNet::Location::family
int family() const
Returns the preferred name resolution address family, or AF_UNSPEC.
Definition: glocation.cpp:126
G::Str::isUInt
static bool isUInt(const std::string &s)
Returns true if the string can be converted into an unsigned integer without throwing an exception...
Definition: gstr.cpp:304
GNet::Location::Location
Location(const std::string &host, const std::string &service, int family=AF_UNSPEC)
Constructor taking a host/service string.
Definition: glocation.cpp:32
GNet::Location::resolveTrivially
void resolveTrivially()
If host() and service() are already in address format then do a trivial update() so that the location...
Definition: glocation.cpp:136
GNet::Location::host
std::string host() const
Returns the remote host name, as passed in to the constructor.
Definition: glocation.cpp:116
GNet::Location::updateTime
G::EpochTime updateTime() const
Returns the time of the last update() or zero if never update()d.
Definition: glocation.cpp:175
gresolver.h