void CEDClients::RunGlobalStatsRequests(DWORD tNow) { // Don't send stat requests or time out servers if we're not stable if ( Network.IsFirewalled(CHECK_UDP) ) return; if ( m_nLastServerKey != 0 ) { // We are waiting for a response if ( tNow > m_tLastServerStats + Settings.Connection.TimeoutHandshake ) { // Timed out m_nLastServerKey = 0; theApp.Message( MSG_DEBUG, _T("Time-out waiting for ed2k server status") ); CQuickLock pLock( HostCache.eDonkey.m_pSection ); CHostCacheHostPtr pHost = HostCache.eDonkey.Find( &m_pLastServer ); if ( pHost ) { pHost->m_tFailure = pHost->m_tStats; pHost->m_nFailures ++; // If we've had multiple failures, remove the host if ( pHost->m_nFailures > 3 ) { theApp.Message( MSG_INFO, _T("Removing ed2k server %s"), pHost->m_sName ); HostCache.eDonkey.Remove( pHost ); } } // Reset the timer so we query another server right away // m_tLastServerStats = 0; } } if ( tNow > m_tLastServerStats + Settings.eDonkey.StatsGlobalThrottle ) // Limit requests to every 30 minutes { // Get the current time (in seconds) const DWORD tSecs = static_cast< DWORD >( time( NULL ) ); CQuickLock oLock( HostCache.eDonkey.m_pSection ); // Loop through servers in the host cache for ( CHostCacheIterator i = HostCache.eDonkey.Begin() ; i != HostCache.eDonkey.End() ; ++i ) { CHostCacheHostPtr pHost = (*i); //CString str; //str.Format( _T(" -Name:%s Last Stats:%d UDP flags:%08X"), pHost->m_sName, pHost->m_tStats, pHost->m_nUDPFlags ); //theApp.Message( MSG_INFO, str ); // Check if this server could be asked for stats if ( ( pHost->CanQuery( tSecs ) ) && // If it hasn't been searched recently ( ( tSecs > pHost->m_tStats + Settings.eDonkey.StatsServerThrottle ) || // AND we have not checked this host in a week ( ( pHost->m_nFailures > 0 ) && ( tSecs > pHost->m_tStats + 8*60*60 ) ) ) && // OR last check failed, have not checked in 8 hours ( pHost->m_nUDPFlags == 0 || m_bAllServersDone ) ) // AND it has no flags set OR we have checked all servers { CSingleLock pLock( &Network.m_pSection ); if ( ! pLock.Lock( 200 ) ) continue; // Don't ask current neighbours for stats if ( ! Neighbours.Get( pHost->m_pAddress ) ) { // Send a request for stats to this server if ( ! pHost->m_sName.IsEmpty() ) theApp.Message( MSG_INFO, _T("Sending status request to ed2k server %s"), pHost->m_sName ); else theApp.Message( MSG_INFO, _T("Sending status request to ed2k server %s"), (LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) ); RequestServerStatus( &pHost->m_pAddress, pHost->m_nPort ); pHost->m_tStats = tSecs; m_tLastServerStats = tNow; m_pLastServer = pHost->m_pAddress; return; } } } m_bAllServersDone = TRUE; // We have checked all known servers, we may go back and re-query any that didn't respond. m_tLastServerStats = tNow; // Try again later. (we don't want to keep running this section, it's a little slow) } }
void CEDClients::RunGlobalStatsRequests(DWORD tNow) { CHostCacheHost *pHost; // Don't send stat requests or time out servers if we're not stable if ( ! Datagrams.IsStable() ) return; if ( m_nLastServerKey != 0 ) { // We are waiting for a response if ( tNow > m_tLastServerStats + Settings.Connection.TimeoutHandshake ) { CSingleLock pLock( &Network.m_pSection ); if ( ! pLock.Lock( 250 ) ) return; // Timed out m_nLastServerKey = 0; theApp.Message( MSG_DEBUG, _T("Time-out waiting for ed2k server status") ); pHost = HostCache.eDonkey.Find( &m_pLastServer ); if ( pHost ) { pHost->m_tFailure = pHost->m_tStats; pHost->m_nFailures ++; // If we've had multiple failures, remove the host if ( pHost->m_nFailures > 3 ) { theApp.Message( MSG_DEFAULT, _T("Removing ed2k server %s"), pHost->m_sName ); HostCache.eDonkey.Remove( pHost ); } } // Reset the timer so we query another server right away // m_tLastServerStats = 0; pLock.Unlock(); } } if ( tNow > m_tLastServerStats + Settings.eDonkey.StatsGlobalThrottle ) // Limit requests to every 30 minutes { // We are due to send another stats request CSingleLock pLock( &Network.m_pSection ); if ( ! pLock.Lock( 250 ) ) return; // Get the current time (in seconds) DWORD tSecs = time( NULL ); // Loop through servers in the host cache for ( pHost = HostCache.eDonkey.GetNewest() ; pHost ; pHost = pHost->m_pPrevTime ) { /*CString strT; strT.Format( _T(" -Name:%s Last Stats:%d UDP flags:%08X"), pHost->m_sName, pHost->m_tStats, pHost->m_nUDPFlags ); theApp.Message( MSG_DEFAULT, strT );*/ // Check if this server could be asked for stats if ( ( pHost->CanQuery( tSecs ) ) && // If it hasn't been searched recently ( ( tSecs > pHost->m_tStats + Settings.eDonkey.StatsServerThrottle ) || // AND we have not checked this host in a week OR ( ( pHost->m_nFailures > 0 ) && ( tSecs > pHost->m_tStats + 8*60*60 ) ) ) && // -last check failed, have not checked in 8 hours ( ( pHost->m_nUDPFlags == 0 ) || // AND it has no flags set OR ( m_bAllServersDone ) ) ) // -we have checked all servers { // Don't ask current neighbours for stats if ( ! Neighbours.Get( &pHost->m_pAddress ) ) { // Send a request for stats to this server if ( pHost->m_sName.GetLength() ) theApp.Message( MSG_DEFAULT, _T("Sending status request to ed2k server %s"), pHost->m_sName ); else theApp.Message( MSG_DEFAULT, _T("Sending status request to ed2k server %s"), (LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) ); RequestServerStatus( &pHost->m_pAddress, pHost->m_nPort ); pHost->m_tStats = tSecs; m_tLastServerStats = tNow; m_pLastServer = pHost->m_pAddress; return; } } } pLock.Unlock(); // We have checked all known servers, we may go back and re-query any that didn't respond. m_bAllServersDone = TRUE; // Try again later. (we don't want to keep running this section, it's a little slow) m_tLastServerStats = tNow; } }