gloox  1.0.1
socks5bytestream.cpp
1 /*
2  Copyright (c) 2006-2012 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 "bytestreamdatahandler.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  : Bytestream( Bytestream::S5B, logInstance, initiator, target, sid ),
29  m_manager( manager ), m_connection( 0 ), m_socks5( 0 ), m_connected( false )
30  {
31  if( connection && connection->state() == StateConnected )
32  m_open = true;
33 
34  setConnectionImpl( connection );
35  }
36 
38  {
39  if( m_open )
40  close();
41 
42  if( m_socks5 )
43  delete m_socks5;
44  }
45 
47  {
48  if( m_socks5 )
49  delete m_socks5; // deletes m_connection as well
50 
51  m_connection = connection;
52 
53  SHA sha;
54  sha.feed( m_sid );
55  sha.feed( m_initiator.full() );
56  sha.feed( m_target.full() );
57  m_socks5 = new ConnectionSOCKS5Proxy( this, connection, m_logInstance, sha.hex(), 0 );
58  }
59 
61  {
62  if( !m_connection || !m_socks5 || !m_manager )
63  return false;
64 
65  if( m_open )
66  return true;
67 
68  StreamHostList::const_iterator it = m_hosts.begin();
69  for( ; it != m_hosts.end(); ++it )
70  {
71  if( ++it == m_hosts.end() )
72  m_connected = true;
73  --it; // FIXME ++it followed by --it is kinda ugly
74  m_connection->setServer( (*it).host, (*it).port );
75  if( m_socks5->connect() == ConnNoError )
76  {
77  m_proxy = (*it).jid;
78  m_connected = true;
79  return true;
80  }
81  }
82 
83  m_manager->acknowledgeStreamHost( false, JID(), EmptyString );
84  return false;
85  }
86 
87  bool SOCKS5Bytestream::send( const std::string& data )
88  {
89  if( !m_open || !m_connection || !m_socks5 || !m_manager )
90  return false;
91 
92  return m_socks5->send( data );
93  }
94 
96  {
97  if( !m_connection || !m_socks5 || !m_manager )
98  return ConnNotConnected;
99 
100  return m_socks5->recv( timeout );
101  }
102 
103  void SOCKS5Bytestream::activate()
104  {
105  m_open = true;
106  if( m_handler )
108  }
109 
111  {
112  if( m_open && m_handler )
113  {
114  m_open = false;
115  m_connected = false;
116  m_socks5->disconnect();
118  }
119  }
120 
121  void SOCKS5Bytestream::handleReceivedData( const ConnectionBase* /*connection*/, const std::string& data )
122  {
123  if( !m_handler )
124  return;
125 
126  if( !m_open )
127  {
128  m_open = true;
130  }
131 
132 // if( !m_open && data.length() == 2 && data[0] == 0x05 && data[1] == 0x00 )
133 // {
134 // printf( "received acknowleding zero byte, stream is now open\n" );
135 // m_open = true;
136 // m_handler->handleBytestream5Open( this );
137 // return;
138 // }
139 
140  if( m_open )
141  m_handler->handleBytestreamData( this, data );
142  }
143 
144  void SOCKS5Bytestream::handleConnect( const ConnectionBase* /*connection*/ )
145  {
146  m_manager->acknowledgeStreamHost( true, m_proxy, m_sid );
147  }
148 
149  void SOCKS5Bytestream::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError /*reason*/ )
150  {
151  close();
152  }
153 
154 }