00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "socks5bytestreamserver.h"
00015 #include "connectiontcpserver.h"
00016 #include "mutexguard.h"
00017 #include "util.h"
00018
00019 namespace gloox
00020 {
00021
00022 SOCKS5BytestreamServer::SOCKS5BytestreamServer( const LogSink& logInstance, int port,
00023 const std::string& ip )
00024 : m_tcpServer( 0 ), m_logInstance( logInstance ), m_ip( ip ), m_port( port )
00025 {
00026 m_tcpServer = new ConnectionTCPServer( this, m_logInstance, m_ip, m_port );
00027 }
00028
00029 SOCKS5BytestreamServer::~SOCKS5BytestreamServer()
00030 {
00031 if( m_tcpServer )
00032 delete m_tcpServer;
00033
00034 ConnectionMap::const_iterator it = m_connections.begin();
00035 for( ; it != m_connections.end(); ++it )
00036 delete (*it).first;
00037 }
00038
00039 ConnectionError SOCKS5BytestreamServer::listen()
00040 {
00041 if( m_tcpServer )
00042 return m_tcpServer->connect();
00043
00044 return ConnNotConnected;
00045 }
00046
00047 ConnectionError SOCKS5BytestreamServer::recv( int timeout )
00048 {
00049 if( !m_tcpServer )
00050 return ConnNotConnected;
00051
00052 ConnectionError ce = m_tcpServer->recv( timeout );
00053 if( ce != ConnNoError )
00054 return ce;
00055
00056 ConnectionMap::const_iterator it = m_connections.begin();
00057 ConnectionMap::const_iterator it2;
00058 while( it != m_connections.end() )
00059 {
00060 it2 = it++;
00061 (*it2).first->recv( timeout );
00062 }
00063
00064
00065
00066 {
00067 ConnectionList::iterator it = m_oldConnections.begin();
00068 ConnectionList::iterator it2;
00069 while( it != m_oldConnections.end() )
00070 {
00071 it2 = it++;
00072 delete (*it2);
00073 m_oldConnections.erase( it2 );
00074 }
00075 }
00076
00077 return ConnNoError;
00078 }
00079
00080 void SOCKS5BytestreamServer::stop()
00081 {
00082 if( m_tcpServer )
00083 {
00084 m_tcpServer->disconnect();
00085 m_tcpServer->cleanup();
00086 }
00087 }
00088
00089 ConnectionBase* SOCKS5BytestreamServer::getConnection( const std::string& hash )
00090 {
00091 MutexGuard mg( m_mutex );
00092
00093 ConnectionMap::iterator it = m_connections.begin();
00094 for( ; it != m_connections.end(); ++it )
00095 {
00096 if( (*it).second.hash == hash )
00097 {
00098 ConnectionBase* conn = (*it).first;
00099 conn->registerConnectionDataHandler( 0 );
00100 m_connections.erase( it );
00101 return conn;
00102 }
00103 }
00104
00105 return 0;
00106 }
00107
00108 void SOCKS5BytestreamServer::registerHash( const std::string& hash )
00109 {
00110 MutexGuard mg( m_mutex );
00111 m_hashes.push_back( hash );
00112 }
00113
00114 void SOCKS5BytestreamServer::removeHash( const std::string& hash )
00115 {
00116 MutexGuard mg( m_mutex );
00117 m_hashes.remove( hash );
00118 }
00119
00120 void SOCKS5BytestreamServer::handleIncomingConnection( ConnectionBase* connection )
00121 {
00122 connection->registerConnectionDataHandler( this );
00123 ConnectionInfo ci;
00124 ci.state = StateUnnegotiated;
00125 m_connections[connection] = ci;
00126 }
00127
00128 void SOCKS5BytestreamServer::handleReceivedData( const ConnectionBase* connection,
00129 const std::string& data )
00130 {
00131 ConnectionMap::iterator it = m_connections.find( const_cast<ConnectionBase*>( connection ) );
00132 if( it == m_connections.end() )
00133 return;
00134
00135 switch( (*it).second.state )
00136 {
00137 case StateDisconnected:
00138 (*it).first->disconnect();
00139 break;
00140 case StateUnnegotiated:
00141 {
00142 char c[2];
00143 c[0] = 0x05;
00144 c[1] = (char)0xFF;
00145 (*it).second.state = StateDisconnected;
00146
00147 if( data.length() >= 3 && data[0] == 0x05 )
00148 {
00149 unsigned int sz = ( data.length() - 2 < (unsigned int)data[1] )
00150 ? ( data.length() - 2 )
00151 : ( (unsigned int)data[1] );
00152 for( unsigned int i = 2; i < sz + 2; ++i )
00153 {
00154 if( data[i] == 0x00 )
00155 {
00156 c[1] = 0x00;
00157 (*it).second.state = StateAuthAccepted;
00158 break;
00159 }
00160 }
00161 }
00162 (*it).first->send( std::string( c, 2 ) );
00163 break;
00164 }
00165 case StateAuthmethodAccepted:
00166
00167 break;
00168 case StateAuthAccepted:
00169 {
00170 std::string reply = data;
00171 if( reply.length() < 2 )
00172 reply.resize( 2 );
00173
00174 reply[0] = 0x05;
00175 reply[1] = 0x01;
00176 (*it).second.state = StateDisconnected;
00177
00178 if( data.length() == 47 && data[0] == 0x05 && data[1] == 0x01 && data[2] == 0x00
00179 && data[3] == 0x03 && data[4] == 0x28 && data[45] == 0x00 && data[46] == 0x00 )
00180 {
00181 const std::string hash = data.substr( 5, 40 );
00182
00183 HashMap::const_iterator ith = m_hashes.begin();
00184 for( ; ith != m_hashes.end() && (*ith) != hash; ++ith )
00185 ;
00186
00187 if( ith != m_hashes.end() )
00188 {
00189 reply[1] = 0x00;
00190 (*it).second.hash = hash;
00191 (*it).second.state = StateDestinationAccepted;
00192 }
00193 }
00194 (*it).first->send( reply );
00195 break;
00196 }
00197 case StateDestinationAccepted:
00198 case StateActive:
00199
00200 break;
00201 }
00202 }
00203
00204 void SOCKS5BytestreamServer::handleConnect( const ConnectionBase* )
00205 {
00206
00207 }
00208
00209 void SOCKS5BytestreamServer::handleDisconnect( const ConnectionBase* connection,
00210 ConnectionError )
00211 {
00212 m_connections.erase( const_cast<ConnectionBase*>( connection ) );
00213 m_oldConnections.push_back( connection );
00214 }
00215
00216 }