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