BOOL CEDClients::OnAccept(CConnection* pConnection) { if ( ! Network.IsConnected() || ( Settings.Connection.RequireForTransfers && ! Settings.eDonkey.Enabled ) ) { theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_DISABLED, (LPCTSTR)pConnection->m_sAddress ); return FALSE; } CSingleLock oTransfersLock( &Transfers.m_pSection ); if ( ! oTransfersLock.Lock( 250 ) ) { theApp.Message( MSG_DEBUG, _T("Rejecting ed2k connection from %s, network core overloaded."), (LPCTSTR)pConnection->m_sAddress ); // protocolNames[ PROTOCOL_ED2K ] return FALSE; } CSingleLock oEDClientsLock( &m_pSection ); if ( ! oEDClientsLock.Lock( 250 ) ) { theApp.Message( MSG_DEBUG, _T("Rejecting ed2k connection from %s, network core overloaded."), (LPCTSTR)pConnection->m_sAddress ); // protocolNames[ PROTOCOL_ED2K ] return FALSE; } if ( IsFull() ) { // Even if we're full, we still need to accept connections from clients we have queued, etc if ( ( GetByIP( &pConnection->m_pHost.sin_addr ) == NULL ) || ( IsOverloaded() ) ) { theApp.Message( MSG_DEBUG, _T("Rejecting ed2k connection from %s, max client connections reached."), (LPCTSTR)pConnection->m_sAddress ); // protocolNames[ PROTOCOL_ED2K ] return FALSE; } else { theApp.Message( MSG_DEBUG, _T("Accepting ed2k connection from %s despite client connection limit."), (LPCTSTR)pConnection->m_sAddress ); // protocolNames[ PROTOCOL_ED2K ] } } if ( CEDClient* pClient = new CEDClient() ) { pClient->AttachTo( pConnection ); return TRUE; } return FALSE; }
BOOL CEDClients::OnAccept(CConnection* pConnection) { ASSERT( pConnection != NULL ); if ( Settings.Connection.RequireForTransfers && ! Settings.eDonkey.EnableToday ) { theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_DISABLED, (LPCTSTR)pConnection->m_sAddress ); return FALSE; } CSingleLock pLock( &Transfers.m_pSection ); if ( ! pLock.Lock( 250 ) ) return FALSE; if ( IsFull() ) { // Even if we're full, we still need to accept connections from clients we have queued, etc if ( ( GetByIP( &pConnection->m_pHost.sin_addr ) == NULL ) || ( IsOverloaded() ) ) { theApp.Message( MSG_DEBUG, _T("Rejecting ed2k connection from %s, max client connections reached."), (LPCTSTR)pConnection->m_sAddress ); return FALSE; } else { theApp.Message( MSG_DEBUG, _T("Accepting ed2k connection from %s despite client connection limit."), (LPCTSTR)pConnection->m_sAddress ); } } CEDClient* pClient = new CEDClient(); pClient->AttachTo( pConnection ); return TRUE; }
BOOL CEDClients::OnPacket(const SOCKADDR_IN* pHost, CEDPacket* pPacket) { pPacket->SmartDump( pHost, TRUE, FALSE ); CSingleLock pLock( &Transfers.m_pSection ); if ( ! pLock.Lock( 250 ) ) { theApp.Message( MSG_DEBUG, _T("Rejecting ed2k UDP from %s, network core overloaded."), (LPCTSTR)CString( inet_ntoa( (IN_ADDR&)pHost->sin_addr ) ) ); return FALSE; } CQuickLock oLock( m_pSection ); switch ( pPacket->m_nType ) { case ED2K_C2C_UDP_REASKFILEPING: if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); if ( ! pClient->OnUdpReask( pPacket ) ) Datagrams.Send( pHost, CEDPacket::New( ED2K_C2C_UDP_FILENOTFOUND, ED2K_PROTOCOL_EMULE ) ); } else { Datagrams.Send( pHost, CEDPacket::New( ED2K_C2C_UDP_FILENOTFOUND, ED2K_PROTOCOL_EMULE ) ); } break; case ED2K_C2C_UDP_REASKACK: if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpReaskAck( pPacket ); } break; case ED2K_C2C_UDP_QUEUEFULL: if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpQueueFull( pPacket ); } break; case ED2K_C2C_UDP_FILENOTFOUND: if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpFileNotFound( pPacket ); } break; case ED2K_S2CG_SERVERSTATUS: OnServerStatus( pHost, pPacket ); break; case ED2K_S2CG_SEARCHRESULT: case ED2K_S2CG_FOUNDSOURCES: { // Correct port value. (UDP port is TCP port + 4) SOCKADDR_IN pAddress = *pHost; pAddress.sin_port = htons( ntohs( pHost->sin_port ) - 4 ); CQuickLock oLock( HostCache.eDonkey.m_pSection ); // Check server details in host cache DWORD nServerFlags = Settings.eDonkey.DefaultServerFlags; CHostCacheHostPtr pServer = HostCache.eDonkey.Find( &pAddress.sin_addr ); if ( pServer && pServer->m_nUDPFlags ) nServerFlags = pServer->m_nUDPFlags; // Decode packet and create hits if ( CQueryHit* pHits = CQueryHit::FromEDPacket( pPacket, &pAddress, nServerFlags ) ) { if ( pPacket->m_nType == ED2K_S2CG_SEARCHRESULT ) { Network.OnQueryHits( pHits ); } else { Downloads.OnQueryHits( pHits ); pHits->Delete(); } } } break; #ifdef _DEBUG default: CString tmp; tmp.Format( _T("Unknown ED2K UDP packet from %s:%u."), (LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ), htons( pHost->sin_port ) ); pPacket->Debug( tmp ); #endif // Debug } return TRUE; }
// UDP packet received BOOL CEDClients::OnUDP(SOCKADDR_IN* pHost, CEDPacket* pPacket) { CSingleLock pLock( &Transfers.m_pSection ); switch ( pPacket->m_nType ) { case ED2K_C2C_UDP_REASKFILEPING: if ( ! pLock.Lock( 100 ) ) return FALSE; if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); if ( ! pClient->OnUdpReask( pPacket ) ) { Datagrams.Send( pHost, CEDPacket::New( ED2K_C2C_UDP_FILENOTFOUND, ED2K_PROTOCOL_EMULE ) ); } } else { Datagrams.Send( pHost, CEDPacket::New( ED2K_C2C_UDP_FILENOTFOUND, ED2K_PROTOCOL_EMULE ) ); } break; case ED2K_C2C_UDP_REASKACK: if ( ! pLock.Lock( 100 ) ) return FALSE; if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpReaskAck( pPacket ); } break; case ED2K_C2C_UDP_QUEUEFULL: if ( ! pLock.Lock( 100 ) ) return FALSE; if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpQueueFull( pPacket ); } break; case ED2K_C2C_UDP_FILENOTFOUND: if ( ! pLock.Lock( 100 ) ) return FALSE; if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpFileNotFound( pPacket ); } break; case ED2K_S2CG_SERVERSTATUS: OnServerStatus( pHost, pPacket ); break; case ED2K_S2CG_SEARCHRESULT: case ED2K_S2CG_FOUNDSOURCES: // Correct port value. (UDP port is TCP port + 4) pHost->sin_port = htons( ntohs( pHost->sin_port ) - 4 ); // Check server details in host cache CHostCacheHost *pServer; DWORD nServerFlags = Settings.eDonkey.DefaultServerFlags; pServer = HostCache.eDonkey.Find( &pHost->sin_addr ); if ( pServer && pServer->m_nUDPFlags ) { nServerFlags = pServer->m_nUDPFlags; } // Decode packet and create hits if ( CQueryHit* pHits = CQueryHit::FromPacket( pPacket, pHost, nServerFlags ) ) { Downloads.OnQueryHits( pHits ); if ( pPacket->m_nType == ED2K_S2CG_SEARCHRESULT ) Network.OnQueryHits( pHits ); else pHits->Delete(); } break; } return TRUE; }
BOOL CEDClients::OnPacket(const SOCKADDR_IN* pHost, CEDPacket* pPacket) { pPacket->SmartDump( pHost, TRUE, FALSE ); if ( pPacket->m_nEdProtocol == ED2K_PROTOCOL_EDONKEY ) { switch ( pPacket->m_nType ) { case ED2K_S2CG_SERVERSTATUS: return OnServerStatus( pHost, pPacket ); case ED2K_S2CG_SEARCHRESULT: case ED2K_S2CG_FOUNDSOURCES: return OnServerSearchResult( pHost, pPacket ); #ifdef _DEBUG default: CString tmp; tmp.Format( _T("Unknown packet from %s:%u."), (LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ), htons( pHost->sin_port ) ); pPacket->Debug( tmp ); #endif // _DEBUG } } else { CSingleLock pLock( &Transfers.m_pSection ); if ( ! pLock.Lock( 250 ) ) { theApp.Message( MSG_ERROR, _T("Rejecting %s connection from %s, network core overloaded."), protocolNames[ PROTOCOL_ED2K ], (LPCTSTR)CString( inet_ntoa( (IN_ADDR&)pHost->sin_addr ) ) ); return FALSE; } CQuickLock oLock( m_pSection ); switch ( pPacket->m_nType ) { case ED2K_C2C_UDP_REASKFILEPING: if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); if ( ! pClient->OnUdpReask( pPacket ) ) { Datagrams.Send( pHost, CEDPacket::New( ED2K_C2C_UDP_FILENOTFOUND, ED2K_PROTOCOL_EMULE ) ); } } else { Datagrams.Send( pHost, CEDPacket::New( ED2K_C2C_UDP_FILENOTFOUND, ED2K_PROTOCOL_EMULE ) ); } break; case ED2K_C2C_UDP_REASKACK: if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpReaskAck( pPacket ); } break; case ED2K_C2C_UDP_QUEUEFULL: if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpQueueFull( pPacket ); } break; case ED2K_C2C_UDP_FILENOTFOUND: if ( CEDClient* pClient = GetByIP( &pHost->sin_addr ) ) { pClient->m_nUDP = ntohs( pHost->sin_port ); pClient->OnUdpFileNotFound( pPacket ); } break; #ifdef _DEBUG default: CString tmp; tmp.Format( _T("Unknown packet from %s:%u."), (LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ), htons( pHost->sin_port ) ); pPacket->Debug( tmp ); #endif // _DEBUG } } return TRUE; }