gloox
1.0
|
00001 /* 00002 Copyright (c) 2006-2009 by Jakob Schroeter <js@camaya.net> 00003 This file is part of the gloox library. http://camaya.net/gloox 00004 00005 This software is distributed under a license. The full license 00006 agreement can be found in the file LICENSE in this distribution. 00007 This software may not be copied, modified, sold or distributed 00008 other than expressed in the named license agreement. 00009 00010 This software is distributed without any warranty. 00011 */ 00012 00013 00014 #include "socks5bytestream.h" 00015 #include "bytestreamdatahandler.h" 00016 #include "clientbase.h" 00017 #include "connectionbase.h" 00018 #include "connectionsocks5proxy.h" 00019 #include "sha.h" 00020 #include "logsink.h" 00021 00022 namespace gloox 00023 { 00024 00025 SOCKS5Bytestream::SOCKS5Bytestream( SOCKS5BytestreamManager* manager, ConnectionBase* connection, 00026 LogSink& logInstance, const JID& initiator, const JID& target, 00027 const std::string& sid ) 00028 : Bytestream( Bytestream::S5B, logInstance, initiator, target, sid ), 00029 m_manager( manager ), m_connection( 0 ), m_socks5( 0 ), m_connected( false ) 00030 { 00031 if( connection && connection->state() == StateConnected ) 00032 m_open = true; 00033 00034 setConnectionImpl( connection ); 00035 } 00036 00037 SOCKS5Bytestream::~SOCKS5Bytestream() 00038 { 00039 if( m_open ) 00040 close(); 00041 00042 if( m_socks5 ) 00043 delete m_socks5; 00044 } 00045 00046 void SOCKS5Bytestream::setConnectionImpl( ConnectionBase* connection ) 00047 { 00048 if( m_socks5 ) 00049 delete m_socks5; // deletes m_connection as well 00050 00051 m_connection = connection; 00052 00053 SHA sha; 00054 sha.feed( m_sid ); 00055 sha.feed( m_initiator.full() ); 00056 sha.feed( m_target.full() ); 00057 m_socks5 = new ConnectionSOCKS5Proxy( this, connection, m_logInstance, sha.hex(), 0 ); 00058 } 00059 00060 bool SOCKS5Bytestream::connect() 00061 { 00062 if( !m_connection || !m_socks5 || !m_manager ) 00063 return false; 00064 00065 if( m_open ) 00066 return true; 00067 00068 StreamHostList::const_iterator it = m_hosts.begin(); 00069 for( ; it != m_hosts.end(); ++it ) 00070 { 00071 if( ++it == m_hosts.end() ) 00072 m_connected = true; 00073 --it; // FIXME ++it followed by --it is kinda ugly 00074 m_connection->setServer( (*it).host, (*it).port ); 00075 if( m_socks5->connect() == ConnNoError ) 00076 { 00077 m_proxy = (*it).jid; 00078 m_connected = true; 00079 return true; 00080 } 00081 } 00082 00083 m_manager->acknowledgeStreamHost( false, JID(), EmptyString ); 00084 return false; 00085 } 00086 00087 bool SOCKS5Bytestream::send( const std::string& data ) 00088 { 00089 if( !m_open || !m_connection || !m_socks5 || !m_manager ) 00090 return false; 00091 00092 return m_socks5->send( data ); 00093 } 00094 00095 ConnectionError SOCKS5Bytestream::recv( int timeout ) 00096 { 00097 if( !m_connection || !m_socks5 || !m_manager ) 00098 return ConnNotConnected; 00099 00100 return m_socks5->recv( timeout ); 00101 } 00102 00103 void SOCKS5Bytestream::activate() 00104 { 00105 m_open = true; 00106 if( m_handler ) 00107 m_handler->handleBytestreamOpen( this ); 00108 } 00109 00110 void SOCKS5Bytestream::close() 00111 { 00112 if( m_open && m_handler ) 00113 { 00114 m_open = false; 00115 m_connected = false; 00116 m_socks5->disconnect(); 00117 m_handler->handleBytestreamClose( this ); 00118 } 00119 } 00120 00121 void SOCKS5Bytestream::handleReceivedData( const ConnectionBase* /*connection*/, const std::string& data ) 00122 { 00123 if( !m_handler ) 00124 return; 00125 00126 if( !m_open ) 00127 { 00128 m_open = true; 00129 m_handler->handleBytestreamOpen( this ); 00130 } 00131 00132 // if( !m_open && data.length() == 2 && data[0] == 0x05 && data[1] == 0x00 ) 00133 // { 00134 // printf( "received acknowleding zero byte, stream is now open\n" ); 00135 // m_open = true; 00136 // m_handler->handleBytestream5Open( this ); 00137 // return; 00138 // } 00139 00140 if( m_open ) 00141 m_handler->handleBytestreamData( this, data ); 00142 } 00143 00144 void SOCKS5Bytestream::handleConnect( const ConnectionBase* /*connection*/ ) 00145 { 00146 m_manager->acknowledgeStreamHost( true, m_proxy, m_sid ); 00147 } 00148 00149 void SOCKS5Bytestream::handleDisconnect( const ConnectionBase* /*connection*/, ConnectionError /*reason*/ ) 00150 { 00151 if( m_handler && m_connected ) 00152 m_handler->handleBytestreamClose( this ); 00153 } 00154 00155 }