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 #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 util::clearList( m_oldConnections );
00065 return ConnNoError;
00066 }
00067
00068 void SOCKS5BytestreamServer::stop()
00069 {
00070 if( m_tcpServer )
00071 {
00072 m_tcpServer->disconnect();
00073 m_tcpServer->cleanup();
00074 }
00075 }
00076
00077 int SOCKS5BytestreamServer::localPort() const
00078 {
00079 if( m_tcpServer )
00080 return m_tcpServer->localPort();
00081
00082 return m_port;
00083 }
00084
00085 const std::string SOCKS5BytestreamServer::localInterface() const
00086 {
00087 if( m_tcpServer )
00088 return m_tcpServer->localInterface();
00089
00090 return m_ip;
00091 }
00092
00093 ConnectionBase* SOCKS5BytestreamServer::getConnection( const std::string& hash )
00094 {
00095 util::MutexGuard mg( m_mutex );
00096
00097 ConnectionMap::iterator it = m_connections.begin();
00098 for( ; it != m_connections.end(); ++it )
00099 {
00100 if( (*it).second.hash == hash )
00101 {
00102 ConnectionBase* conn = (*it).first;
00103 conn->registerConnectionDataHandler( 0 );
00104 m_connections.erase( it );
00105 return conn;
00106 }
00107 }
00108
00109 return 0;
00110 }
00111
00112 void SOCKS5BytestreamServer::registerHash( const std::string& hash )
00113 {
00114 util::MutexGuard mg( m_mutex );
00115 m_hashes.push_back( hash );
00116 }
00117
00118 void SOCKS5BytestreamServer::removeHash( const std::string& hash )
00119 {
00120 util::MutexGuard mg( m_mutex );
00121 m_hashes.remove( hash );
00122 }
00123
00124 void SOCKS5BytestreamServer::handleIncomingConnection( ConnectionBase* , ConnectionBase* connection )
00125 {
00126 connection->registerConnectionDataHandler( this );
00127 ConnectionInfo ci;
00128 ci.state = StateUnnegotiated;
00129 m_connections[connection] = ci;
00130 }
00131
00132 void SOCKS5BytestreamServer::handleReceivedData( const ConnectionBase* connection,
00133 const std::string& data )
00134 {
00135 ConnectionMap::iterator it = m_connections.find( const_cast<ConnectionBase*>( connection ) );
00136 if( it == m_connections.end() )
00137 return;
00138
00139 switch( (*it).second.state )
00140 {
00141 case StateDisconnected:
00142 (*it).first->disconnect();
00143 break;
00144 case StateUnnegotiated:
00145 {
00146 char c[2];
00147 c[0] = 0x05;
00148 c[1] = (char)(unsigned char)0xFF;
00149 (*it).second.state = StateDisconnected;
00150
00151 if( data.length() >= 3 && data[0] == 0x05 )
00152 {
00153 unsigned int sz = ( data.length() - 2 < static_cast<unsigned int>( data[1] ) )
00154 ? static_cast<unsigned int>( data.length() - 2 )
00155 : static_cast<unsigned int>( data[1] );
00156 for( unsigned int i = 2; i < sz + 2; ++i )
00157 {
00158 if( data[i] == 0x00 )
00159 {
00160 c[1] = 0x00;
00161 (*it).second.state = StateAuthAccepted;
00162 break;
00163 }
00164 }
00165 }
00166 (*it).first->send( std::string( c, 2 ) );
00167 break;
00168 }
00169 case StateAuthmethodAccepted:
00170
00171 break;
00172 case StateAuthAccepted:
00173 {
00174 std::string reply = data;
00175 if( reply.length() < 2 )
00176 reply.resize( 2 );
00177
00178 reply[0] = 0x05;
00179 reply[1] = 0x01;
00180 (*it).second.state = StateDisconnected;
00181
00182 if( data.length() == 47 && data[0] == 0x05 && data[1] == 0x01 && data[2] == 0x00
00183 && data[3] == 0x03 && data[4] == 0x28 && data[45] == 0x00 && data[46] == 0x00 )
00184 {
00185 const std::string hash = data.substr( 5, 40 );
00186
00187 HashMap::const_iterator ith = m_hashes.begin();
00188 for( ; ith != m_hashes.end() && (*ith) != hash; ++ith )
00189 ;
00190
00191 if( ith != m_hashes.end() )
00192 {
00193 reply[1] = 0x00;
00194 (*it).second.hash = hash;
00195 (*it).second.state = StateDestinationAccepted;
00196 }
00197 }
00198 (*it).first->send( reply );
00199 break;
00200 }
00201 case StateDestinationAccepted:
00202 case StateActive:
00203
00204 break;
00205 }
00206 }
00207
00208 void SOCKS5BytestreamServer::handleConnect( const ConnectionBase* )
00209 {
00210
00211 }
00212
00213 void SOCKS5BytestreamServer::handleDisconnect( const ConnectionBase* connection,
00214 ConnectionError )
00215 {
00216 m_connections.erase( const_cast<ConnectionBase*>( connection ) );
00217 m_oldConnections.push_back( connection );
00218 }
00219
00220 }