VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
glocation.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
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 "gnet.h"
23 #include "gstr.h"
24 #include "glocation.h"
25 #include "gresolver.h"
26 #include "gassert.h"
27 
28 namespace
29 {
30  const char * host_service_separators = ":/." ;
31 }
32 
33 GNet::Location::Location( const std::string & host , const std::string & service , int family ) :
34  m_host(host) ,
35  m_service(service) ,
36  m_address_valid(false) ,
37  m_address(Address::defaultAddress()) ,
38  m_family(family) ,
39  m_dgram(false) ,
40  m_update_time(0U) ,
41  m_socks(false) ,
42  m_socks_far_port(0U)
43 {
44  G_DEBUG( "GNet::Location::ctor: unresolved location [" << displayString() << "]" ) ;
45 }
46 
47 GNet::Location::Location( const std::string & location_string , int family ) :
48  m_host(head(sockless(location_string))) ,
49  m_service(tail(sockless(location_string))) ,
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(false) ,
56  m_socks_far_port(0U)
57 {
58  m_socks = socked( location_string , m_socks_far_host , m_socks_far_port ) ;
59  if( m_host.empty() || m_service.empty() )
60  throw InvalidFormat( location_string ) ;
61  G_DEBUG( "GNet::Location::ctor: unresolved location [" << displayString() << "]" << (m_socks?" (using socks)":"") ) ;
62 }
63 
64 std::string GNet::Location::sockless( const std::string & s )
65 {
66  // "far-host:far-port@sockserver-host:sockserver-port"
67  return G::Str::tail( s , s.find('@') , s ) ;
68 }
69 
70 bool GNet::Location::socked( const std::string & s , std::string & far_host , unsigned int & far_port )
71 {
72  std::string::size_type pos = s.find('@') ;
73  if( pos != std::string::npos )
74  {
75  std::string ss = G::Str::head( s , pos ) ;
76  far_host = G::Str::head( ss , ss.find_last_of(host_service_separators) ) ;
77  far_port = G::Str::toUInt( G::Str::tail( ss , ss.find_last_of(host_service_separators) ) ) ;
78  }
79  return pos != std::string::npos ;
80 }
81 
82 std::string GNet::Location::head( const std::string & s )
83 {
84  return G::Str::head( s , s.find_last_of(host_service_separators) ) ;
85 }
86 
87 std::string GNet::Location::tail( const std::string & s )
88 {
89  return G::Str::tail( s , s.find_last_of(host_service_separators) ) ;
90 }
91 
92 std::string GNet::Location::host() const
93 {
94  return m_host ;
95 }
96 
97 std::string GNet::Location::service() const
98 {
99  return m_service ;
100 }
101 
103 {
104  return m_family ;
105 }
106 
108 {
109  return m_dgram ;
110 }
111 
113 {
114  std::string reason ;
115  if( !resolved() && Address::validStrings(m_host,m_service,&reason) )
116  update( Address(m_host,G::Str::toUInt(m_service)) , std::string() ) ;
117 }
118 
120 {
121  return m_address_valid ;
122 }
123 
125 {
126  return m_address ;
127 }
128 
129 void GNet::Location::update( const Address & address , const std::string & name )
130 {
131  G_ASSERT( m_family == AF_UNSPEC || address.domain() == m_family ) ;
132  m_address = address ;
133  m_family = address.domain() ; // not family()
134  m_address_valid = true ;
135  m_canonical_name = name ;
136  m_update_time = G::DateTime::now() ;
137  G_DEBUG( "GNet::Location::ctor: resolved location [" << displayString() << "]" ) ;
138 }
139 
140 std::string GNet::Location::name() const
141 {
142  return m_canonical_name ;
143 }
144 
145 std::string GNet::Location::displayString() const
146 {
147  const char * ipvx = m_family == AF_UNSPEC ? "ip" : ( m_family == AF_INET ? "ipv4" : "ipv6" ) ;
148  return resolved() ? address().displayString() : (m_host+"/"+m_service+"/"+ipvx) ;
149 }
150 
152 {
153  return m_update_time ;
154 }
155 
157 {
158  return m_socks ;
159 }
160 
161 unsigned int GNet::Location::socksFarPort() const
162 {
163  return m_socks_far_port ;
164 }
165 
166 std::string GNet::Location::socksFarHost() const
167 {
168  return m_socks_far_host ;
169 }
170 
171 /// \file glocation.cpp
A subsecond-resolution timestamp based on a time_t.
Definition: gdatetime.h:39
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:55
bool socks() const
Returns true if a socks location.
Definition: glocation.cpp:156
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::string displayString() const
Returns a string representation for logging and debug.
Definition: glocation.cpp:145
static std::string tail(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
Definition: gstr.cpp:1051
static EpochTime now()
Returns the current epoch time.
static unsigned int toUInt(const std::string &s)
Converts string 's' to an unsigned int.
Definition: gstr.cpp:450
bool dgram() const
Returns true if the name resolution should be specifically for datagram sockets.
Definition: glocation.cpp:107
std::string name() const
Returns the remote canonical name.
Definition: glocation.cpp:140
static std::string head(const std::string &in, std::string::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:1037
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:129
Address address() const
Returns the remote address.
Definition: glocation.cpp:124
std::string socksFarHost() const
Returns the port for the socks far server.
Definition: glocation.cpp:166
bool resolved() const
Returns true after update() has been called.
Definition: glocation.cpp:119
int domain() const
Returns the address 'domain', eg. PF_INET.
std::string service() const
Returns the remote service name, as passed in to the constructor.
Definition: glocation.cpp:97
unsigned int socksFarPort() const
Returns the port number for the socks far server.
Definition: glocation.cpp:161
int family() const
Returns the preferred name resolution address family, or AF_UNSPEC.
Definition: glocation.cpp:102
Location(const std::string &host, const std::string &service, int family=AF_UNSPEC)
Constructor taking a host/service string.
Definition: glocation.cpp:33
void resolveTrivially()
If host() and service() are already in address format then do a trivial update() so that the location...
Definition: glocation.cpp:112
std::string host() const
Returns the remote host name, as passed in to the constructor.
Definition: glocation.cpp:92
G::EpochTime updateTime() const
Returns the time of the last update() or zero if never update()d.
Definition: glocation.cpp:151