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

📄 datagrams.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 3 页
字号:

BOOL CDatagrams::OnPong(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	
	BOOL bRelayed = FALSE;
	CHAR szType[9];
	DWORD nLength;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nOffset = pPacket->m_nPosition + nLength;
		if ( strcmp( szType, "RELAY" ) == 0 ) bRelayed = TRUE;
		pPacket->m_nPosition = nOffset;
	}
	
	if ( ! bRelayed ) return TRUE;
	
	if ( ! Network.IsConnectedTo( &pHost->sin_addr ) ) m_bStable = TRUE;
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDatagrams QUERY packet handler

BOOL CDatagrams::OnQuery(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	CQuerySearch* pSearch = CQuerySearch::FromPacket( pPacket, pHost );
	
	if ( pSearch == NULL || ! pSearch->m_bUDP )
	{
		if ( pSearch ) delete pSearch;
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_QUERY,
			(LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ) );
		Statistics.Current.Gnutella2.Dropped++;
		return FALSE;
	}
	
	if ( Security.IsDenied( &pSearch->m_pEndpoint.sin_addr ) )
	{
		delete pSearch;
		Statistics.Current.Gnutella2.Dropped++;
		return FALSE;
	}
	
	if ( ! Network.QueryKeys->Check( pSearch->m_pEndpoint.sin_addr.S_un.S_addr, pSearch->m_nKey ) )
	{
		DWORD nKey = Network.QueryKeys->Create( pSearch->m_pEndpoint.sin_addr.S_un.S_addr );
		
		CString strNode = inet_ntoa( pSearch->m_pEndpoint.sin_addr );
		theApp.Message( MSG_DEBUG, _T("Issuing correction for node %s's query key for %s"),
			(LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ), (LPCTSTR)strNode );
		
		CG2Packet* pAnswer = CG2Packet::New( G2_PACKET_QUERY_KEY_ANS, TRUE );
		pAnswer->WritePacket( "QK", 4 );
		pAnswer->WriteLongBE( nKey );
		
		if ( pHost->sin_addr.S_un.S_addr != pSearch->m_pEndpoint.sin_addr.S_un.S_addr )
		{
			pAnswer->WritePacket( "SNA", 4 );
			pAnswer->WriteLongLE( pHost->sin_addr.S_un.S_addr );
		}
		
		Send( &pSearch->m_pEndpoint, pAnswer, TRUE );
		
		delete pSearch;
		return TRUE;
	}
	
	if ( ! Network.QueryRoute->Add( &pSearch->m_pGUID, &pSearch->m_pEndpoint ) )
	{
		CG2Packet* pAnswer = CG2Packet::New( G2_PACKET_QUERY_ACK, TRUE );
		pAnswer->WritePacket( "D", 8 );
		pAnswer->WriteLongLE( Network.m_pHost.sin_addr.S_un.S_addr );
		pAnswer->WriteShortBE( htons( Network.m_pHost.sin_port ) );
		pAnswer->WriteShortBE( 0 );
		pAnswer->WriteByte( 0 );
		pAnswer->Write( &pSearch->m_pGUID, sizeof(GGUID) );
		Send( &pSearch->m_pEndpoint, pAnswer, TRUE );
		
		delete pSearch;
		Statistics.Current.Gnutella2.Dropped++;
		return TRUE;
	}
	
	Neighbours.RouteQuery( pSearch, pPacket, NULL, TRUE );
	
	Network.OnQuerySearch( pSearch );
	
	CLocalSearch pLocal( pSearch, &pSearch->m_pEndpoint );
	pLocal.Execute();
	
	Send( &pSearch->m_pEndpoint, Neighbours.CreateQueryWeb( &pSearch->m_pGUID ), TRUE );
	
	delete pSearch;
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDatagrams QUERY ACK packet handler

BOOL CDatagrams::OnQueryAck(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	CHostCacheHost* pCache = HostCache.Gnutella2.Add( &pHost->sin_addr, htons( pHost->sin_port ) );
	if ( pCache ) pCache->m_tAck = pCache->m_nFailures = 0;
	
	GGUID pGUID;
	
	if ( SearchManager.OnQueryAck( pPacket, pHost, &pGUID ) )
	{
		CNeighbour* pNeighbour = NULL;
		SOCKADDR_IN pEndpoint;

		if ( Network.QueryRoute->Lookup( &pGUID, &pNeighbour, &pEndpoint ) )
		{
			// TODO: Add a "FR" from tag
			
			if ( pNeighbour != NULL && pNeighbour->m_nNodeType == ntLeaf )
			{
				pNeighbour->Send( pPacket, FALSE, FALSE );
			}
			else
			{
				// Don't route it on via UDP
			}
		}
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDatagrams HIT packet handler

BOOL CDatagrams::OnHit(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	int nHops = 0;
	CQueryHit* pHits = CQueryHit::FromPacket( pPacket, &nHops );
	
	if ( pHits == NULL )
	{
		pPacket->Debug( _T("BadHit") );
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_HIT,
			(LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ) );
		Statistics.Current.Gnutella2.Dropped++;
		return FALSE;
	}
	
	if ( Security.IsDenied( &pHits->m_pAddress ) || nHops > (int)Settings.Gnutella1.MaximumTTL )
	{
		pHits->Delete();
		Statistics.Current.Gnutella2.Dropped++;
		return FALSE;
	}
	
	Network.NodeRoute->Add( &pHits->m_pClientID, pHost );
	
	if ( SearchManager.OnQueryHits( pHits ) )
	{
		Network.RouteHits( pHits, pPacket );
	}
	
	Network.OnQueryHits( pHits );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDatagrams QUERY KEY REQUEST packet handler

BOOL CDatagrams::OnQueryKeyRequest(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	if ( ! Neighbours.IsHub() ) return FALSE;
	
	DWORD nRequestedAddress = pHost->sin_addr.S_un.S_addr;
	WORD nRequestedPort = ntohs( pHost->sin_port );
	DWORD nSendingAddress = pHost->sin_addr.S_un.S_addr;
	
	if ( pPacket->m_bCompound )
	{
		CHAR szType[9];
		DWORD nLength;
		
		while ( pPacket->ReadPacket( szType, nLength ) )
		{
			DWORD nOffset = pPacket->m_nPosition + nLength;
			
			if ( strcmp( szType, "RNA" ) == 0 && nLength >= 6 )
			{
				nRequestedAddress	= pPacket->ReadLongLE();
				nRequestedPort		= pPacket->ReadShortBE();
			}
			else if ( strcmp( szType, "SNA" ) == 0 && nLength >= 4 )
			{
				nSendingAddress		= pPacket->ReadLongLE();
			}
			
			pPacket->m_nPosition = nOffset;
		}
	}
	
	CString strNode = inet_ntoa( *(IN_ADDR*)&nRequestedAddress );
	theApp.Message( MSG_DEBUG, _T("Node %s asked for a query key for node %s:%i"),
		(LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ), (LPCTSTR)strNode, nRequestedPort );
	
	if ( Network.IsFirewalledAddress( &nRequestedAddress, TRUE ) || 0 == nRequestedPort ) return TRUE;
	
	DWORD nKey = Network.QueryKeys->Create( nRequestedAddress );
	
	CG2Packet* pAnswer = CG2Packet::New( G2_PACKET_QUERY_KEY_ANS, TRUE );
	
	pAnswer->WritePacket( "QK", 4 );
	pAnswer->WriteLongBE( nKey );
	
	if ( nRequestedAddress != nSendingAddress )
	{
		pAnswer->WritePacket( "SNA", 4 );
		pAnswer->WriteLongLE( nSendingAddress );
	}
	
	Send( (IN_ADDR*)&nRequestedAddress, nRequestedPort, pAnswer, TRUE );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDatagrams QUERY KEY ANSWER packet handler

BOOL CDatagrams::OnQueryKeyAnswer(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return FALSE;
	
	DWORD nKey = 0, nAddress = 0;
	
	CHAR szType[9];
	DWORD nLength;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nOffset = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "QK" ) == 0 && nLength >= 4 )
		{
			nKey = pPacket->ReadLongBE();
		}
		else if ( strcmp( szType, "SNA" ) == 0 && nLength >= 4 )
		{
			nAddress = pPacket->ReadLongLE();
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	theApp.Message( MSG_DEBUG, _T("Got a query key for %s:%lu: 0x%x"),
		(LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ), htons( pHost->sin_port ), nKey );
	
	CHostCacheHost* pCache = HostCache.Gnutella2.Add(
		&pHost->sin_addr, htons( pHost->sin_port ) );
	
	if ( pCache != NULL ) pCache->SetKey( nKey );
	
	if ( nAddress != 0 && nAddress != Network.m_pHost.sin_addr.S_un.S_addr )
	{
		if ( CNeighbour* pNeighbour = Neighbours.Get( (IN_ADDR*)&nAddress ) )
		{
			BYTE* pOut = pPacket->WriteGetPointer( 11, 0 );
			
			*pOut++ = 0x50;
			*pOut++ = 6;
			*pOut++ = 'Q';
			*pOut++ = 'N';
			*pOut++ = 'A';
			*pOut++ = pHost->sin_addr.S_un.S_un_b.s_b1;
			*pOut++ = pHost->sin_addr.S_un.S_un_b.s_b2;
			*pOut++ = pHost->sin_addr.S_un.S_un_b.s_b3;
			*pOut++ = pHost->sin_addr.S_un.S_un_b.s_b4;
			
			if ( pPacket->m_bBigEndian )
			{
				*pOut++ = (BYTE)( pHost->sin_port & 0xFF );
				*pOut++ = (BYTE)( pHost->sin_port >> 8 );
			}
			else
			{
				*pOut++ = (BYTE)( pHost->sin_port >> 8 );
				*pOut++ = (BYTE)( pHost->sin_port & 0xFF );
			}
			
			pNeighbour->Send( pPacket, FALSE, FALSE );
		}
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDatagrams PUSH packet handler

BOOL CDatagrams::OnPush(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	DWORD nLength = pPacket->GetRemaining();
	
	if ( ! pPacket->SkipCompound( nLength, 6 ) )
	{
		pPacket->Debug( _T("BadPush") );
		Statistics.Current.Gnutella2.Dropped++;
		return FALSE;
	}
	
	DWORD nAddress	= pPacket->ReadLongLE();
	WORD nPort		= pPacket->ReadShortBE();
	
	if ( Security.IsDenied( (IN_ADDR*)&nAddress ) ||
		 Network.IsFirewalledAddress( &nAddress ) )
	{
		Statistics.Current.Gnutella2.Dropped++;
		return TRUE;
	}
	
	Handshakes.PushTo( (IN_ADDR*)&nAddress, nPort );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDatagrams CRAWL packet handler

BOOL CDatagrams::OnCrawlRequest(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return FALSE;
	
	BOOL bWantLeaves	= FALSE;
	BOOL bWantNames		= FALSE;
	BOOL bWantGPS		= FALSE;
	
	CHAR szType[9];
	DWORD nLength;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nNext = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "RLEAF" ) == 0 )
		{
			bWantLeaves = TRUE;
		}
		else if ( strcmp( szType, "RNAME" ) == 0 )
		{
			bWantNames = TRUE;
		}
		else if ( strcmp( szType, "RGPS" ) == 0 )
		{
			bWantGPS = TRUE;
		}
		
		pPacket->m_nPosition = nNext;
	}
	
	pPacket = CG2Packet::New( G2_PACKET_CRAWL_ANS, TRUE );
	
	CString strNick;
	DWORD nGPS = 0;
	
	if ( bWantNames ) strNick = MyProfile.GetNick();
	if ( bWantGPS ) nGPS = MyProfile.GetPackedGPS();
	
	pPacket->WritePacket( "SELF", 16 + ( strNick.GetLength() ? pPacket->GetStringLen( strNick ) + 6 : 0 ) + ( nGPS ? 5 + 4 : 0 ), TRUE );
	
	pPacket->WritePacket( "NA", 6 );
	pPacket->WriteLongLE( Network.m_pHost.sin_addr.S_un.S_addr );
	pPacket->WriteShortBE( htons( Network.m_pHost.sin_port ) );
	
	pPacket->WritePacket( "HS", 2 );
	pPacket->WriteShortBE( Neighbours.GetCount( -1, -1, ntLeaf ) );
	
	if ( strNick.GetLength() )
	{
		pPacket->WritePacket( "NAME", pPacket->GetStringLen( strNick) );
		pPacket->WriteString( strNick, FALSE );
	}
	
	if ( nGPS )
	{
		pPacket->WritePacket( "GPS", 4 );
		pPacket->WriteLongBE( nGPS );
	}
	
	for ( POSITION pos = Neighbours.GetIterator() ; pos ; )
	{
		CNeighbour* pNeighbour = Neighbours.GetNext( pos );
		if ( pNeighbour->m_nState < nrsConnected ) continue;
		
		int nExtraLen = 0;
		strNick.Empty();
		nGPS = 0;
		
		if ( pNeighbour->m_nProtocol == PROTOCOL_G2 )
		{
			if ( CGProfile* pProfile = ((CG2Neighbour*)pNeighbour)->m_pProfile )
			{
				if ( bWantNames ) strNick = pProfile->GetNick();
				if ( bWantGPS ) nGPS = pProfile->GetPackedGPS();
				
				if ( strNick.GetLength() ) nExtraLen += 6 + pPacket->GetStringLen( strNick );
				if ( nGPS ) nExtraLen += 9;
			}
		}
		
		if ( pNeighbour->m_nProtocol == PROTOCOL_G2 &&
			 pNeighbour->m_nNodeType != ntLeaf )
		{
			pPacket->WritePacket( "NH", 16 + nExtraLen, TRUE );
			
			pPacket->WritePacket( "NA", 6 );
			pPacket->WriteLongLE( pNeighbour->m_pHost.sin_addr.S_un.S_addr );
			pPacket->WriteShortBE( htons( pNeighbour->m_pHost.sin_port ) );
			
			pPacket->WritePacket( "HS", 2 );
			pPacket->WriteShortBE( (WORD)((CG2Neighbour*)pNeighbour)->m_nLeafCount );
		}
		else if ( pNeighbour->m_nNodeType == ntLeaf && bWantLeaves )
		{
			pPacket->WritePacket( "NL", 10 + nExtraLen, TRUE );

			pPacket->WritePacket( "NA", 6 );
			pPacket->WriteLongLE( pNeighbour->m_pHost.sin_addr.S_un.S_addr );
			pPacket->WriteShortBE( htons( pNeighbour->m_pHost.sin_port ) );
		}
		else
		{
			nExtraLen = 0;
		}
		
		if ( nExtraLen > 0 )
		{
			if ( strNick.GetLength() )
			{
				pPacket->WritePacket( "NAME", pPacket->GetStringLen( strNick ) );
				pPacket->WriteString( strNick, FALSE );
			}
			
			if ( nGPS )
			{
				pPacket->WritePacket( "GPS", 4 );
				pPacket->WriteLongBE( nGPS );
			}
		}
	}
	
	Send( pHost, pPacket );
	
	return TRUE;
}

BOOL CDatagrams::OnCrawlAnswer(SOCKADDR_IN* pHost, CG2Packet* pPacket)
{
	CrawlSession.OnCrawl( pHost, pPacket );
	return TRUE;
}

⌨️ 快捷键说明

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