gloox  0.9.9.12
socks5bytestream.cpp
1 /*
2  Copyright (c) 2006-2008 by Jakob Schroeter <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 #include "socks5bytestream.h"
15 #include "socks5bytestreamdatahandler.h"
16 #include "clientbase.h"
17 #include "connectionbase.h"
18 #include "connectionsocks5proxy.h"
19 #include "sha.h"
20 #include "logsink.h"
21 
22 namespace gloox
23 {
24 
25  SOCKS5Bytestream::SOCKS5Bytestream( SOCKS5BytestreamManager* manager, ConnectionBase* connection,
26  LogSink& logInstance, const JID& initiator, const JID& target,
27  const std::string& sid )
28  : m_manager( manager ), m_connection( 0 ), m_socks5( 0 ), m_logInstance( logInstance ),
29  m_socks5BytestreamDataHandler( 0 ), m_initiator( initiator ), m_target( target ),
30  m_sid( sid ), m_open( false )
31  {
32  if( connection && connection->state() == StateConnected )
33  m_open = true;
34 
35  setConnectionImpl( connection );
36  }
37 
39  {
40  if( m_open )
41  close();
42 
43  if( m_socks5 )
44  delete m_socks5;
45  }
46 
48  {
49  if( m_socks5 )
50  delete m_socks5; // deletes m_connection as well
51 
52  m_connection = connection;
53 
54  SHA sha;
55  sha.feed( m_sid );
56  sha.feed( m_initiator.full() );
57  sha.feed( m_target.full() );
58  m_socks5 = new ConnectionSOCKS5Proxy( this, connection, m_logInstance, sha.hex(), 0 );
59  }
60 
62  {
63  if( !m_connection || !m_socks5 || !m_manager )
64  return false;
65 
66  if( m_open )
67  return true;
68 
69  StreamHostList::const_iterator it = m_hosts.begin();
70  for( ; it != m_hosts.end(); ++it )
71  {
72  m_connection->setServer( (*it).host, (*it).port );
73  if( m_socks5->connect() == ConnNoError )
74  {
75  m_proxy = (*it).jid;
76  return true;
77  }
78  }
79 
80  m_manager->acknowledgeStreamHost( false, JID(), std::string() );
81  return false;
82  }
83 
84  bool SOCKS5Bytestream::send( const std::string& data )
85  {
86  if( !m_open || !m_connection || !m_socks5 || !m_manager )
87  return false;
88 
89  return m_socks5->send( data );
90  }
91 
93  {
94  if( !m_connection || !m_socks5 || !m_manager )
95  return ConnNotConnected;
96 
97  return m_socks5->recv( timeout );
98  }
99 
100  void SOCKS5Bytestream::activate()
101  {
102  m_open = true;
103  if( m_socks5BytestreamDataHandler )
104  m_socks5BytestreamDataHandler->handleSOCKS5Open( this );
105  }
106 
108  {
109  if( m_open )
110  {
111  m_open = false;
112  m_socks5->disconnect();
113  m_socks5BytestreamDataHandler->handleSOCKS5Close( this );
114  }
115  }
116 
117  void SOCKS5Bytestream::handleReceivedData( const ConnectionBase* /*connection*/, const std::string& data )
118  {
119  if( !m_socks5BytestreamDataHandler )
120  return;
121 
122  if( !m_open )
123  {
124  m_open = true;
125  m_socks5BytestreamDataHandler->handleSOCKS5Open( this );
126  }
127 
128 // if( !m_open && data.length() == 2 && data[0] == 0x05 && data[1] == 0x00 )
129 // {
130 // printf( "received acknowleding zero byte, stream is now open\n" );
131 // m_open = true;
132 // m_socks5BytestreamDataHandler->handleSOCKS5Open( this );
133 // return;
134 // }
135 
136  if( m_open )
137  m_socks5BytestreamDataHandler->handleSOCKS5Data( this, data );
138  }
139 
140  void SOCKS5Bytestream::handleConnect( const ConnectionBase* /*connection*/ )
141  {
142  m_manager->acknowledgeStreamHost( true, m_proxy, m_sid );
143  }
144 
145  void SOCKS5Bytestream::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError /*reason*/ )
146  {
147  if( m_socks5BytestreamDataHandler )
148  m_socks5BytestreamDataHandler->handleSOCKS5Close( this );
149  }
150 
151 }