VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gsimpleclient.h
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 /// \file gsimpleclient.h
19 ///
20 
21 #ifndef G_SIMPLE_CLIENT_H
22 #define G_SIMPLE_CLIENT_H
23 
24 #include "gdef.h"
25 #include "gnet.h"
26 #include "gaddress.h"
27 #include "gconnection.h"
28 #include "gexception.h"
29 #include "geventhandler.h"
30 #include "gresolver.h"
31 #include "glocation.h"
32 #include "gtimer.h"
33 #include "gsocket.h"
34 #include "gsocketprotocol.h"
35 #include "gevent.h"
36 #include <string>
37 
38 namespace GNet
39 {
40  class SimpleClient ;
41 }
42 
43 /// \class GNet::SimpleClient
44 /// A class for making an outgoing connection to a remote server, with
45 /// support for socket-level protocols such as TLS/SSL and SOCKS 4a.
46 ///
47 /// The class handles name-to-address resolution, deals with connection
48 /// issues, reads incoming data, and manages flow-control when sending.
49 /// The implementation uses the SocketProtocol class in order to do TLS/SSL;
50 /// see sslConnect().
51 ///
52 /// Name-to-address lookup is performed if the supplied Location object
53 /// does not contain an address. This can be done synchronously or
54 /// asynchronously. The results of the lookup can be obtained via the
55 /// remoteLocation() method and possibly fed back to the next SimpleClient
56 /// that connects to the same host/service in order to implement name lookup
57 /// cacheing (see GNet::ClientPtr). However, most operating systems implement
58 /// their own name lookup cacheing, so this is not terribly useful in practice.
59 ///
61 {
62 public:
63  enum ConnectStatus { Success , Failure , ImmediateSuccess } ;
64  enum State { Idle , Resolving , Connecting , Connected , Socksing , Testing } ;
65  G_EXCEPTION( DnsError , "dns error" ) ;
66  G_EXCEPTION( ConnectError , "connect failure" ) ;
67  G_EXCEPTION( SocksError , "socks error" ) ;
68  G_EXCEPTION( NotConnected , "socket not connected" ) ;
69  typedef std::string::size_type size_type ;
70 
71  SimpleClient( const Location & remote_info ,
72  bool bind_local_address = false ,
73  const Address & local_address = Address::defaultAddress() ,
74  bool sync_dns = synchronousDnsDefault() ,
75  unsigned int secure_connection_timeout = 0U ) ;
76  ///< Constructor.
77 
78  void connect() ;
79  ///< Initates a connection to the remote server. Calls back
80  ///< to onConnect() when complete (non-reentrantly). Throws
81  ///< on error.
82 
83  bool connected() const ;
84  ///< Returns true if connected to the peer.
85 
86  virtual std::pair<bool,Address> localAddress() const override ;
87  ///< Override from Connection. Returns the local
88  ///< address. Pair.first is false on error.
89  ///< Override from GNet::Connection.
90 
91  virtual std::pair<bool,Address> peerAddress() const override ;
92  ///< Override from Connection. Returns the peer
93  ///< address. Pair.first is false on error.
94  ///< Override from GNet::Connection.
95 
96  virtual std::string peerCertificate() const override ;
97  ///< Returns the peer's TLS certificate.
98  ///< Override from GNet::Connection.
99 
100  static bool synchronousDnsDefault() ;
101  ///< Returns true if DNS queries should normally be
102  ///< synchronous on this platform. Used to default the
103  ///< relevant constructor parameter.
104 
105  Location remoteLocation() const ;
106  ///< Returns a Location structure containing the
107  ///< result of host() and service() name lookup if
108  ///< available.
109 
110  void updateLocation( const Location & ) ;
111  ///< Updates the constructor's Location object with
112  ///< the given one as long as both objects have the
113  ///< same host and service name. This is only useful
114  ///< immediately after construction and before
115  ///< re-entering the event loop.
116 
117  virtual void readEvent() override ;
118  ///< Override from GNet::EventHandler.
119 
120  virtual void writeEvent() override ;
121  ///< Override from GNet::EventHandler.
122 
123  bool send( const std::string & data , std::string::size_type offset = 0 ) ;
124  ///< Returns true if all sent, or false if flow
125  ///< control was asserted. Throws on error.
126 
127 protected:
128  virtual ~SimpleClient() ;
129  ///< Destructor.
130 
131  StreamSocket & socket() ;
132  ///< Returns a reference to the socket. Throws if not connected.
133 
134  const StreamSocket & socket() const ;
135  ///< Returns a const reference to the socket. Throws if not connected.
136 
137  virtual void onConnect() = 0 ;
138  ///< Called once connected.
139 
140  virtual void onConnectImp() ;
141  ///< An alternative to onConnect() for private implementation
142  ///< classes. The default implementation does nothing.
143 
144  virtual void onSendComplete() = 0 ;
145  ///< Called when all residual data from send() has been sent.
146 
147  virtual void onSendImp() ;
148  ///< Called from within send().
149 
150  void sslConnect() ;
151  ///< Starts TLS/SSL client-side negotiation.
152 
153  static bool connectError( const std::string & reason ) ;
154  ///< Returns true if the reason string implies the
155  ///< SimpleClient::connect() failed.
156 
157  std::string logId() const ;
158  ///< Returns a identification string for logging purposes.
159  ///< Not guaranteed to stay the same during the lifetime
160  ///< of the object.
161 
162 private:
163  SimpleClient( const SimpleClient& ) ; // not implemented
164  void operator=( const SimpleClient& ) ; // not implemented
165  void close() ;
166  void startConnecting() ;
167  void bindLocalAddress( const Address & ) ;
168  void setState( State ) ;
169  void sendSocksRequest() ;
170  bool readSocksResponse() ;
171  void logFlowControlAsserted() const ;
172  void logFlowControlReleased() const ;
173  virtual void onResolved( std::string , Location ) override ; // Override from GNet::Resolver.
174  void onConnectTimer() ;
175  void onWriteable() ;
176 
177 private:
178  unique_ptr<StreamSocket> m_socket ;
179  unique_ptr<SocketProtocol> m_sp ;
180  Resolver m_resolver ;
181  Location m_remote_location ;
182  bool m_bind_local_address ;
183  Address m_local_address ;
184  State m_state ;
185  bool m_sync_dns ;
186  unsigned int m_secure_connection_timeout ;
187  Timer<SimpleClient> m_on_connect_timer ; // zero-length timer
188 } ;
189 
190 #endif
virtual void onConnect()=0
Called once connected.
virtual void writeEvent() override
Override from GNet::EventHandler.
virtual void readEvent() override
Override from GNet::EventHandler.
A class for making an outgoing connection to a remote server, with support for socket-level protocols...
Definition: gsimpleclient.h:60
bool send(const std::string &data, std::string::size_type offset=0)
Returns true if all sent, or false if flow control was asserted.
void sslConnect()
Starts TLS/SSL client-side negotiation.
A class for synchronous or asynchronous network name to address resolution.
Definition: gresolver.h:43
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:55
virtual std::string peerCertificate() const override
Returns the peer's TLS certificate.
bool connected() const
Returns true if connected to the peer.
virtual void onConnectImp()
An alternative to onConnect() for private implementation classes.
An interface used for GNet::Resolver callbacks.
Definition: gresolver.h:49
virtual void onSendComplete()=0
Called when all residual data from send() has been sent.
A class that holds a host/service name pair and the preferred address family (if any), and also the results of a name-to-address lookup, ie.
Definition: glocation.h:51
void connect()
Initates a connection to the remote server.
A derivation of GNet::Socket for a stream socket.
Definition: gsocket.h:245
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number.
Location remoteLocation() const
Returns a Location structure containing the result of host() and service() name lookup if available...
virtual std::pair< bool, Address > localAddress() const override
Override from Connection.
SimpleClient(const Location &remote_info, bool bind_local_address=false, const Address &local_address=Address::defaultAddress(), bool sync_dns=synchronousDnsDefault(), unsigned int secure_connection_timeout=0U)
Constructor.
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:78
std::string logId() const
Returns a identification string for logging purposes.
static bool synchronousDnsDefault()
Returns true if DNS queries should normally be synchronous on this platform.
virtual void onSendImp()
Called from within send().
An interface which provides address information for a network connection.
Definition: gconnection.h:37
virtual ~SimpleClient()
Destructor.
virtual std::pair< bool, Address > peerAddress() const override
Override from Connection.
static bool connectError(const std::string &reason)
Returns true if the reason string implies the SimpleClient::connect() failed.
void updateLocation(const Location &)
Updates the constructor's Location object with the given one as long as both objects have the same ho...
A timer class template in which the timeout is delivered to the specified method. ...
Definition: gtimer.h:110
to deliver data from a socket.
StreamSocket & socket()
Returns a reference to the socket. Throws if not connected.