Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

SearchManager.cpp

Go to the documentation of this file.
00001 //
00002 // SearchManager.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Network.h"
00026 #include "SearchManager.h"
00027 #include "ManagedSearch.h"
00028 #include "QuerySearch.h"
00029 #include "QueryHit.h"
00030 #include "HostCache.h"
00031 #include "G2Packet.h"
00032 
00033 #ifdef _DEBUG
00034 #undef THIS_FILE
00035 static char THIS_FILE[]=__FILE__;
00036 #define new DEBUG_NEW
00037 #endif
00038 
00039 CSearchManager SearchManager;
00040 
00041 
00043 // CSearchManager construction
00044 
00045 CSearchManager::CSearchManager()
00046 {
00047         m_tLastTick = 0;
00048 
00049         m_nPriorityClass = 0;
00050         m_nPriorityCount = 0;
00051 
00052         m_pLastED2KSearch = (GGUID&)GUID_NULL;
00053 }
00054 
00055 CSearchManager::~CSearchManager()
00056 {
00057 }
00058 
00060 // CSearchManager add and remove
00061 
00062 void CSearchManager::Add(CManagedSearch* pSearch)
00063 {
00064         POSITION pos = m_pList.Find( pSearch );
00065         if ( pos == NULL ) m_pList.AddHead( pSearch );
00066 }
00067 
00068 void CSearchManager::Remove(CManagedSearch* pSearch)
00069 {
00070         POSITION pos = m_pList.Find( pSearch );
00071         if ( pos != NULL ) m_pList.RemoveAt( pos );
00072 }
00073 
00075 // CSearchManager list access
00076 
00077 POSITION CSearchManager::GetIterator() const
00078 {
00079         return m_pList.GetHeadPosition();
00080 }
00081 
00082 CManagedSearch* CSearchManager::GetNext(POSITION& pos) const
00083 {
00084         return (CManagedSearch*)m_pList.GetNext( pos );
00085 }
00086 
00087 int CSearchManager::GetCount() const
00088 {
00089         return m_pList.GetCount();
00090 }
00091 
00092 CManagedSearch* CSearchManager::Find(GGUID* pGUID)
00093 {
00094         for ( POSITION pos = m_pList.GetHeadPosition() ; pos ; )
00095         {
00096                 CManagedSearch* pSearch = (CManagedSearch*)m_pList.GetNext( pos );
00097                 if ( pSearch->m_pSearch->m_pGUID == *pGUID ) return pSearch;
00098         }
00099 
00100         return NULL;
00101 }
00102 
00104 // CSearchManager run event (FROM CNetwork THREAD)
00105 
00106 void CSearchManager::OnRun()
00107 {
00108         // Don't run too often to avoid excess CPU use (and router flooding)
00109         DWORD tNow = GetTickCount();
00110         if ( ( tNow - m_tLastTick ) < 125 ) return;
00111         m_tLastTick = tNow;
00112 
00113         // Don't run if we aren't connected
00114         if ( ! Network.IsWellConnected() ) return;
00115 
00116         HostCache.Gnutella2.PruneByQueryAck();
00117 
00118         CSingleLock pLock( &m_pSection );
00119         if ( ! pLock.Lock( 100 ) ) return;
00120 
00121         static int nPriorityFactor[ 3 ] = { 8, 4, 1 };
00122 
00123         if ( m_nPriorityCount >= nPriorityFactor[ m_nPriorityClass ] )
00124         {
00125                 m_nPriorityCount = 0;
00126                 m_nPriorityClass = ( m_nPriorityClass + 1 ) % CManagedSearch::spMax;
00127         }
00128 
00129         for ( int nClass = 0 ; nClass <= CManagedSearch::spMax ; nClass++ )
00130         {
00131                 for ( POSITION pos = GetIterator() ; pos ; )
00132                 {
00133                         POSITION posCur = pos;
00134                         CManagedSearch* pSearch = GetNext( pos );
00135 
00136                         if ( pSearch->m_nPriority == m_nPriorityClass && pSearch->Execute() )
00137                         {
00138                                 m_pList.RemoveAt( posCur );
00139                                 m_pList.AddTail( pSearch );
00140                                 m_nPriorityCount++;
00141                                 return;
00142                         }
00143                 }
00144 
00145                 m_nPriorityCount = 0;
00146                 m_nPriorityClass = ( m_nPriorityClass + 1 ) % CManagedSearch::spMax;
00147         }
00148 }
00149 
00151 // CSearchManager query acknowledgement
00152 
00153 BOOL CSearchManager::OnQueryAck(CG2Packet* pPacket, SOCKADDR_IN* pHost, GGUID* ppGUID)
00154 {
00155         if ( ! pPacket->m_bCompound ) return FALSE;
00156 
00157         DWORD nFromIP = pHost->sin_addr.S_un.S_addr;
00158         DWORD tAdjust = 0, tNow = time( NULL );
00159         DWORD nHubs = 0, nLeaves = 0;
00160         CDWordArray pDone;
00161 
00162         CHAR szType[9];
00163         DWORD nLength;
00164 
00165         theApp.Message( MSG_DEBUG, _T("Processing query acknowledge from %s:"),
00166                 (LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ) );
00167 
00168         while ( pPacket->ReadPacket( szType, nLength ) )
00169         {
00170                 DWORD nOffset = pPacket->m_nPosition + nLength;
00171 
00172                 if ( strcmp( szType, "D" ) == 0 && nLength >= 4 )
00173                 {
00174                         DWORD nAddress = pPacket->ReadLongLE();
00175                         pDone.Add( nAddress );
00176 
00177                         if ( nLength >= 6 )
00178                         {
00179                                 WORD nPort = pPacket->ReadShortBE();
00180 
00181                                 if ( ! Network.IsFirewalledAddress( &nAddress, TRUE ) && nPort )
00182                                 {
00183                                         HostCache.Gnutella2.Add( (IN_ADDR*)&nAddress, nPort, tNow );
00184                                 }
00185                         }
00186 
00187                         if ( nLength >= 8 ) nLeaves += pPacket->ReadShortBE();
00188                         nHubs ++;
00189 
00190                         theApp.Message( MSG_DEBUG, _T("  Done %s"),
00191                                 (LPCTSTR)CString( inet_ntoa( *(IN_ADDR*)&nAddress ) ) );
00192                 }
00193                 else if ( strcmp( szType, "S" ) == 0 && nLength >= 6 )
00194                 {
00195                         DWORD nAddress  = pPacket->ReadLongLE();
00196                         WORD nPort              = pPacket->ReadShortBE();
00197                         DWORD tSeen             = ( nLength >= 10 ) ? pPacket->ReadLongBE() + tAdjust : tNow;
00198 
00199                         theApp.Message( MSG_DEBUG, _T("  Try %s:%lu"),
00200                                 (LPCTSTR)CString( inet_ntoa( *(IN_ADDR*)&nAddress ) ), nPort );
00201 
00202                         if ( ! Network.IsFirewalledAddress( &nAddress, TRUE ) && nPort )
00203                         {
00204                                 HostCache.Gnutella2.Add( (IN_ADDR*)&nAddress, nPort, min( tNow, tSeen ) );
00205                         }
00206                 }
00207                 else if ( strcmp( szType, "TS" ) == 0 && nLength == 4 )
00208                 {
00209                         tAdjust = (LONG)tNow - (LONG)pPacket->ReadLongBE();
00210                 }
00211                 else if ( strcmp( szType, "RA" ) == 0 && nLength >= 2 )
00212                 {
00213                         DWORD nRetryAfter = 0;
00214 
00215                         if ( nLength >= 4 )
00216                         {
00217                                 nRetryAfter = pPacket->ReadLongBE();
00218                         }
00219                         else if ( nLength >= 2 )
00220                         {
00221                                 nRetryAfter = pPacket->ReadShortBE();
00222                         }
00223 
00224                         if ( CHostCacheHost* pHost = HostCache.Gnutella2.Find( (IN_ADDR*)&nFromIP ) )
00225                         {
00226                                 pHost->m_tRetryAfter = tNow + nRetryAfter;
00227                         }
00228                 }
00229                 else if ( strcmp( szType, "FR" ) == 0 && nLength >= 4 )
00230                 {
00231                         nFromIP = pPacket->ReadLongLE();
00232                 }
00233 
00234                 pPacket->m_nPosition = nOffset;
00235         }
00236 
00237         if ( pPacket->GetRemaining() < 16 ) return FALSE;
00238 
00239         GGUID pGUID;
00240         pPacket->Read( &pGUID, sizeof(GGUID) );
00241         if ( ppGUID ) *ppGUID = pGUID;
00242 
00243         CSingleLock pLock( &m_pSection );
00244 
00245         if ( pLock.Lock( 100 ) )
00246         {
00247                 if ( CManagedSearch* pSearch = Find( &pGUID ) )
00248                 {
00249                         pSearch->m_nHubs += nHubs;
00250                         pSearch->m_nLeaves += nLeaves;
00251 
00252                         // (technically not required, but..)
00253                         pSearch->OnHostAcknowledge( nFromIP );
00254 
00255                         for ( int nItem = 0 ; nItem < pDone.GetSize() ; nItem++ )
00256                         {
00257                                 DWORD nAddress = pDone.GetAt( nItem );
00258                                 pSearch->OnHostAcknowledge( nAddress );
00259                         }
00260 
00261                         return FALSE;
00262                 }
00263         }
00264 
00265         return TRUE;
00266 }
00267 
00269 // CSearchManager query hits
00270 
00271 BOOL CSearchManager::OnQueryHits(CQueryHit* pHits)
00272 {
00273         CSingleLock pLock( &m_pSection );
00274         if ( ! pLock.Lock( 100 ) ) return TRUE;
00275 
00276         CManagedSearch* pSearch = Find( &pHits->m_pSearchID );
00277         if ( pSearch == NULL ) return TRUE;
00278 
00279         pSearch->OnHostAcknowledge( *(DWORD*)&pHits->m_pAddress );
00280 
00281         while ( pHits != NULL )
00282         {
00283                 pSearch->m_nHits ++;
00284                 pHits = pHits->m_pNext;
00285         }
00286 
00287         return FALSE;
00288 }
00289 
00291 // CSearchManager query status request
00292 
00293 WORD CSearchManager::OnQueryStatusRequest(GGUID* pGUID)
00294 {
00295         CSingleLock pLock( &m_pSection );
00296         if ( ! pLock.Lock( 100 ) ) return 0xFFFF;
00297 
00298         CManagedSearch* pSearch = Find( pGUID );
00299         if ( pSearch == NULL ) return 0xFFFF;
00300 
00301         return (WORD)min( DWORD(0xFFFE), pSearch->m_nHits );
00302 }

Generated on Thu Dec 15 10:39:48 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2