⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 managedsearch.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		
		// Try to send the search
		
		if ( pPacket != NULL && pNeighbour->SendQuery( m_pSearch, pPacket, TRUE ) )
		{
			theApp.Message( MSG_DEFAULT, IDS_NETWORK_SEARCH_SENT,
				m_pSearch->m_sSearch.GetLength()
					? (LPCTSTR)m_pSearch->m_sSearch
					: _T("URN"),
				(LPCTSTR)CString( inet_ntoa( pNeighbour->m_pHost.sin_addr ) ) );
		}
		
		pPacket->Release();
		
		nCount++;
	}
	
	return ( nCount > 0 );
}

//////////////////////////////////////////////////////////////////////
// CManagedSearch execute the search on the G2 mesh

BOOL CManagedSearch::ExecuteG2Mesh(DWORD tTicks, DWORD tSecs)
{
	// Look at all known Gnutella2 hubs, newest first
	
	for ( CHostCacheHost* pHost = HostCache.Gnutella2.GetNewest() ; pHost ; pHost = pHost->m_pPrevTime )
	{
		// Must be Gnutella2
		
		ASSERT( pHost->m_nProtocol == PROTOCOL_G2 );
		if ( pHost->m_nProtocol != PROTOCOL_G2 ) continue;
		
		// If this host is a neighbour, don't UDP to it
		
		if ( NULL != Neighbours.Get( &pHost->m_pAddress ) ) continue;
		
		// If this host can't be queried now, don't query it
		
		if ( ! pHost->CanQuery( tSecs ) ) continue;
		
		// Check if we have an appropriate query key for this host, and if so,
		// record the receiver address
		
		SOCKADDR_IN* pReceiver = NULL;
		
		if ( pHost->m_nKeyValue == 0 )
		{
			// Well, we already know we don't have a key.. pretty simple
		}
		else if ( Datagrams.IsStable() )
		{
			// If we are "stable", we have to TX/RX our own UDP traffic,
			// so we must have a query key for the local addess
			
			if ( pHost->m_nKeyHost == Network.m_pHost.sin_addr.S_un.S_addr )
				pReceiver = &Network.m_pHost;
			else
				pHost->m_nKeyValue = 0;
		}
		else
		{
			// Make sure we have a query key via one of our neighbours,
			// and ensure we have queried this neighbour
			
			if ( CNeighbour* pNeighbour = Neighbours.Get( (IN_ADDR*)&pHost->m_nKeyHost ) )
			{
				if ( m_pNodes.Lookup( (LPVOID)pHost->m_nKeyHost, (LPVOID&)pReceiver ) )
					pReceiver = &pNeighbour->m_pHost;
				else
					continue;
			}
			else
			{
				pHost->m_nKeyValue = 0;
			}
		}
		
		// Now, if we still have a query key, send the query
		
		if ( pHost->m_nKeyValue != 0 )
		{
			DWORD tLastQuery, nAddress = pHost->m_pAddress.S_un.S_addr;
			ASSERT( pReceiver != NULL );
			
			// Lookup the host
			
			if ( m_pNodes.Lookup( (LPVOID)nAddress, (LPVOID&)tLastQuery ) )
			{
				// Check per-hub requery time
				DWORD nFrequency = Settings.Gnutella2.RequeryDelay;
				nFrequency *= ( m_nPriority + 1 );
				if ( tSecs - tLastQuery < nFrequency ) continue;
			}
			
			// Set the last query time for this host for this search
			
			m_pNodes.SetAt( (LPVOID)nAddress, (LPVOID)tSecs );
			
			// Record the query time on the host, for all searches
			
			pHost->m_tQuery = tSecs;
			if ( pHost->m_tAck == 0 ) pHost->m_tAck = tSecs;
			
			// Try to create a packet
			
			m_pSearch->m_bAndG1 = ( Settings.Gnutella1.EnableToday && m_bAllowG1 );
			CPacket* pPacket = m_pSearch->ToG2Packet( pReceiver, pHost->m_nKeyValue );
			
			// Send the packet if it was created
			
			if ( pPacket != NULL )
			{
				Datagrams.Send( &pHost->m_pAddress, pHost->m_nPort, pPacket, TRUE, this, TRUE );
				
				theApp.Message( MSG_DEBUG, _T("Querying %s"),
					(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) );
				
				return TRUE;
			}
		}
		else if ( tSecs - pHost->m_tKeyTime >= max( Settings.Gnutella2.QueryHostThrottle * 5, 5*60 ) )
		{
			// Timing wise, we can request a query key now -- but first we must figure
			// out who should be the receiver
			
			CNeighbour* pCacheHub = NULL;
			pReceiver = NULL;
			
			if ( Datagrams.IsStable() )
			{
				// If we are stable, we must be the receiver
				pReceiver = &Network.m_pHost;
			}
			else
			{
				// Otherwise, we need to find a neighbour G2 hub who has acked
				// this query already
				
				for ( POSITION pos = Neighbours.GetIterator() ; pos ; pCacheHub = NULL )
				{
					pCacheHub = Neighbours.GetNext( pos );
					LPVOID pTemp;
					
					if ( m_pNodes.Lookup( (LPVOID)pCacheHub->m_pHost.sin_addr.S_un.S_addr, pTemp ) )
					{
						if ( pCacheHub->m_nProtocol == PROTOCOL_G2 &&
							 pCacheHub->m_nNodeType == ntHub )
						{
							pReceiver = &pCacheHub->m_pHost;
							if ( ! ((CG2Neighbour*)pCacheHub)->m_bCachedKeys ) pCacheHub = NULL;
							break;
						}
					}
				}
			}
			
			// If we found a receiver, we can ask for the query key
			
			if ( pCacheHub != NULL )
			{
				// The receiver is a cache-capable hub, so we ask it to return
				// a cached key, or fetch a fresh one
				
				CG2Packet* pPacket = CG2Packet::New( G2_PACKET_QUERY_KEY_REQ, TRUE );
				pPacket->WritePacket( "QNA", 6 );
				pPacket->WriteLongLE( pHost->m_pAddress.S_un.S_addr );
				pPacket->WriteShortBE( pHost->m_nPort );
				pCacheHub->Send( pPacket );
				
				// Report
				
				CString strReceiver = CString( inet_ntoa( pReceiver->sin_addr ) );
				theApp.Message( MSG_DEBUG, _T("Requesting query key from %s through %s"),
					(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ), (LPCTSTR)strReceiver );
				
				if ( pHost->m_tAck == 0 ) pHost->m_tAck = tSecs;
				pHost->m_tKeyTime = tSecs;
				pHost->m_nKeyValue = 0;
				
				return TRUE;
			}
			else if ( pReceiver != NULL )
			{
				// We need to transmit directly to the remote query host
				
				CG2Packet* pPacket = CG2Packet::New( G2_PACKET_QUERY_KEY_REQ, TRUE );
				
				if ( pReceiver == &Network.m_pHost )
				{
					theApp.Message( MSG_DEBUG, _T("Requesting query key from %s"),
						(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) );
				}
				else
				{
					// We are not the receiver, so include receiver address
					pPacket->WritePacket( "RNA", 6 );
					pPacket->WriteLongLE( pReceiver->sin_addr.S_un.S_addr );
					pPacket->WriteShortBE( ntohs( pReceiver->sin_port ) );
					
					CString strReceiver = CString( inet_ntoa( pReceiver->sin_addr ) );
					theApp.Message( MSG_DEBUG, _T("Requesting query key from %s for %s"),
						(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ), (LPCTSTR)strReceiver );
				}
				
				// Send
				
				Datagrams.Send( &pHost->m_pAddress, pHost->m_nPort, pPacket, TRUE, NULL, FALSE );
				
				if ( pHost->m_tAck == 0 ) pHost->m_tAck = tSecs;
				pHost->m_tKeyTime = tSecs;
				pHost->m_nKeyValue = 0;
				
				return TRUE;
			}
		}
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CManagedSearch execute the search on eDonkey2000 servers

BOOL CManagedSearch::ExecuteDonkeyMesh(DWORD tTicks, DWORD tSecs)
{
	for ( CHostCacheHost* pHost = HostCache.eDonkey.GetNewest() ; pHost ; pHost = pHost->m_pPrevTime )
	{
		ASSERT( pHost->m_nProtocol == PROTOCOL_ED2K );
		
		// If this host is a neighbour, don't UDP to it
		
		if ( Neighbours.Get( &pHost->m_pAddress ) ) continue;
		
		// Make sure this host can be queried (now)
		
		if ( pHost->CanQuery( tSecs ) )
		{
			DWORD nAddress = pHost->m_pAddress.S_un.S_addr;
			DWORD tLastQuery;
			
			// Never requery eDonkey2000 servers
			
			if ( m_pNodes.Lookup( (LPVOID)nAddress, (LPVOID&)tLastQuery ) ) continue;
			
			// Set the last query time for this host for this search
			
			m_pNodes.SetAt( (LPVOID)nAddress, (LPVOID)tSecs );
			
			// Record the query time on the host, for all searches
			
			pHost->m_tQuery = tSecs;
			if ( pHost->m_tAck == 0 ) pHost->m_tAck = tSecs;
			
			// Create a packet in the appropriate format
			
			CPacket* pPacket = NULL;
			
			if ( pHost->m_nProtocol == PROTOCOL_ED2K )
			{
				pPacket = m_pSearch->ToEDPacket( TRUE );
			}
			else
			{
				ASSERT( FALSE );
			}
			
			// Send the datagram if possible
			
			if ( pPacket != NULL ) 
			{
				Datagrams.Send( &pHost->m_pAddress, pHost->m_nPort + 4, pPacket, TRUE );
				
				theApp.Message( MSG_DEBUG, _T("Sending query to %s"),
					(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) );
				
				return TRUE;
			}
		}
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CManagedSearch host acknowledgement

void CManagedSearch::OnHostAcknowledge(DWORD nAddress)
{
	DWORD tSecs = time( NULL );
	m_pNodes.SetAt( (LPVOID)nAddress, (LPVOID)tSecs );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -