1 /*
2   Copyright (c) 2006-2019 by Jakob Schröter <js@camaya.net>
3   This file is part of the gloox library. http://camaya.net/gloox
4 
5   This software is distributed under a license. The full license
6   agreement can be found in the file LICENSE in this distribution.
7   This software may not be copied, modified, sold or distributed
8   other than expressed in the named license agreement.
9 
10   This software is distributed without any warranty.
11 */
12 
13 
14 #ifndef SOCKS5BYTESTREAM_H__
15 #define SOCKS5BYTESTREAM_H__
16 
17 #include "bytestream.h"
18 #include "gloox.h"
19 #include "socks5bytestreammanager.h"
20 #include "connectiondatahandler.h"
21 
22 #include <string>
23 
24 namespace gloox
25 {
26 
27   class SOCKS5BytestreamDataHandler;
28   class ConnectionBase;
29   class LogSink;
30 
31   /**
32    * @brief An implementation of a single SOCKS5 Bytestream (@xep{0065}).
33    *
34    * One instance of this class handles one bytestream.
35    *
36    * See SOCKS5BytestreamManager for a detailed description on how to implement
37    * SOCKS5 Bytestreams in your application.
38    *
39    * @author Jakob Schröter <js@camaya.net>
40    * @since 0.9
41    */
42   class GLOOX_API SOCKS5Bytestream : public ConnectionDataHandler, public Bytestream
43   {
44     friend class SOCKS5BytestreamManager;
45 
46     public:
47       /**
48        * Virtual destructor.
49        */
50       virtual ~SOCKS5Bytestream();
51 
52       /**
53        * This function starts the connection process. That is, it attempts to connect
54        * to each of the available StreamHosts. Once a working StreamHosts is found, the
55        * SOCKS5BytestreamManager is notified and the function returns.
56        * @return @b True if a connection to a StreamHost could be established, @b false
57        * otherwise.
58        * @note If @b false is returned you should hand this SOCKS5Bytestream object
59        * to SOCKS5BytestreamManager::dispose() for deletion.
60        * @note Make sure you have a SOCKS5BytestreamDataHandler registered (using
61        * registerSOCKS5BytestreamDataHandler()) before calling this function.
62        */
63       virtual bool connect();
64 
65       /**
66        * Closes the bytestream.
67        */
68       virtual void close();
69 
70       /**
71        * Use this function to send a chunk of data over an open bytestream. There is
72        * no limit for the size of the chunk (other than your machine's memory).
73        * If the stream is not open or has been closed again
74        * (by the remote entity or locally), nothing is sent and @b false is returned.
75        * @param data The block of data to send.
76        * @return @b True if the data has been sent (no guarantee of receipt), @b false
77        * in case of an error.
78        */
79       virtual bool send( const std::string& data );
80 
81       /**
82        * Call this function repeatedly to receive data from the socket. You should even do this
83        * if you use the bytestream to merely @b send data.
84        * @param timeout The timeout to use for select in microseconds. Default of -1 means blocking.
85        * @return The state of the connection.
86        */
87       virtual ConnectionError recv( int timeout = -1 );
88 
89       /**
90        * Sets the connection to use.
91        * @param connection The connection. The bytestream will own the connection, any
92        * previously set connection gets deleted.
93        */
94       void setConnectionImpl( ConnectionBase* connection );
95 
96       /**
97        * This function returns the concrete connection implementation currently in use.
98        * @return The concrete connection implementation.
99        * @since 0.9.7
100        */
connectionImpl()101       ConnectionBase* connectionImpl( ) { return m_connection; }
102 
103       /**
104        * Use this function to set the available StreamHosts. Usually you should not need to
105        * use this function directly.
106        */
setStreamHosts(const StreamHostList & hosts)107       void setStreamHosts( const StreamHostList& hosts ) { m_hosts = hosts; }
108 
109       // reimplemented from ConnectionDataHandler
110       virtual void handleReceivedData( const ConnectionBase* connection, const std::string& data );
111 
112       // reimplemented from ConnectionDataHandler
113       virtual void handleConnect( const ConnectionBase* connection );
114 
115       // reimplemented from ConnectionDataHandler
116       virtual void handleDisconnect( const ConnectionBase* connection, ConnectionError reason );
117 
118     private:
119       SOCKS5Bytestream( SOCKS5BytestreamManager* manager, ConnectionBase* connection,
120                         LogSink& logInstance, const JID& initiator, const JID& target,
121                         const std::string& sid );
122       void activate();
123 
124       SOCKS5BytestreamManager* m_manager;
125       ConnectionBase* m_connection;
126       ConnectionBase* m_socks5;
127       JID m_proxy;
128       bool m_connected;
129 
130       StreamHostList m_hosts;
131 
132   };
133 
134 }
135 
136 #endif // SOCKS5BYTESTREAM_H__
137