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

📄 g2neighbour.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			{
				pPacket->WritePacket( "NH", 14 + 6, TRUE );					// 4
				pPacket->WritePacket( "HS", 2 );							// 4
				pPacket->WriteShortBE( (WORD)pNeighbour->m_nLeafCount );	// 2
				pPacket->WritePacket( "V", 4 );								// 3
				pPacket->WriteString( pNeighbour->m_pVendor->m_sCode );		// 5
			}
			else
			{
				pPacket->WritePacket( "NH", 7 + 6, TRUE );					// 4
				pPacket->WritePacket( "HS", 2 );							// 4
				pPacket->WriteShortBE( (WORD)pNeighbour->m_nLeafCount );	// 2
				pPacket->WriteByte( 0 );									// 1
			}
			
			pPacket->WriteLongLE( pNeighbour->m_pHost.sin_addr.S_un.S_addr );	// 4
			pPacket->WriteShortBE( htons( pNeighbour->m_pHost.sin_port ) );		// 2
		}
	}
	
	int nCount = Settings.Gnutella2.KHLHubCount;
	DWORD tNow = time( NULL );
	
	pPacket->WritePacket( "TS", 4 );
	pPacket->WriteLongBE( time( NULL ) );
	
	for ( CHostCacheHost* pHost = HostCache.Gnutella2.GetNewest() ; pHost && nCount > 0 ; pHost = pHost->m_pPrevTime )
	{
		if (	pHost->CanQuote( tNow ) &&
				Neighbours.Get( &pHost->m_pAddress ) == NULL &&
				pHost->m_pAddress.S_un.S_addr != Network.m_pHost.sin_addr.S_un.S_addr )
		{
			int nLength = 10;
			
			if ( pHost->m_pVendor && pHost->m_pVendor->m_sCode.GetLength() == 4 )
				nLength += 7;
			if ( m_nNodeType == ntLeaf && pHost->m_nKeyValue != 0 && pHost->m_nKeyHost == Network.m_pHost.sin_addr.S_un.S_addr )
				nLength += 8;
			if ( nLength > 10 )
				nLength ++;
			
			pPacket->WritePacket( "CH", nLength, nLength > 10 );
			
			if ( pHost->m_pVendor && pHost->m_pVendor->m_sCode.GetLength() == 4 )
			{
				pPacket->WritePacket( "V", 4 );								// 3
				pPacket->WriteString( pHost->m_pVendor->m_sCode, FALSE );	// 4
			}
			
			if ( m_nNodeType == ntLeaf && pHost->m_nKeyValue != 0 && pHost->m_nKeyHost == Network.m_pHost.sin_addr.S_un.S_addr )
			{
				pPacket->WritePacket( "QK", 4 );							// 4
				pPacket->WriteLongBE( pHost->m_nKeyValue );					// 4
			}
			
			if ( nLength > 10 ) pPacket->WriteByte( 0 );					// 1
			
			pPacket->WriteLongLE( pHost->m_pAddress.S_un.S_addr );			// 4
			pPacket->WriteShortBE( pHost->m_nPort );						// 2
			pPacket->WriteLongBE( pHost->m_tSeen );							// 4
			
			nCount--;
		}
	}
	
	Send( pPacket, TRUE, TRUE );
	
	m_tLastKHL = GetTickCount();
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour KNOWN HUB LIST : receive

BOOL CG2Neighbour::OnKHL(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	
	CHAR szType[9], szInner[9];
	DWORD nLength, nInner;
	BOOL bCompound;
	
	DWORD tNow = time( NULL );
	
	m_pHubGroup->Clear();
	
	while ( pPacket->ReadPacket( szType, nLength, &bCompound ) )
	{
		DWORD nNext = pPacket->m_nPosition + nLength;

		if (	strcmp( szType, "NH" ) == 0 ||
				strcmp( szType, "CH" ) == 0 )
		{
			DWORD nAddress = 0, nKey = 0, tSeen = tNow;
			WORD nPort = 0, nLeafs = 0;
			CString strVendor;
			
			if ( bCompound || 0 == strcmp( szType, "NH" ) )
			{
				while ( pPacket->m_nPosition < nNext && pPacket->ReadPacket( szInner, nInner ) )
				{
					DWORD nNextX = pPacket->m_nPosition + nInner;
					
					if ( strcmp( szInner, "NA" ) == 0 && nInner >= 6 )
					{
						nAddress = pPacket->ReadLongLE();
						nPort = pPacket->ReadShortBE();
					}
					else if ( strcmp( szInner, "V" ) == 0 && nInner >= 4 )
					{
						strVendor = pPacket->ReadString( 4 );
					}
					else if ( strcmp( szInner, "QK" ) == 0 && nInner >= 4 )
					{
						nKey = pPacket->ReadLongBE();
						m_bCachedKeys = TRUE;
					}
					else if ( strcmp( szInner, "TS" ) == 0 && nInner >= 4 )
					{
						tSeen = pPacket->ReadLongBE() + m_tAdjust;
					}
					
					pPacket->m_nPosition = nNextX;
				}
				
				nLength = nNext - pPacket->m_nPosition;
			}
			
			if ( nLength >= 6 )
			{
				nAddress = pPacket->ReadLongLE();
				nPort = pPacket->ReadShortBE();
				if ( nLength >= 10 ) tSeen = pPacket->ReadLongBE() + m_tAdjust;
			}
			
			if ( FALSE == Network.IsFirewalledAddress( &nAddress, TRUE ) )
			{
				CHostCacheHost* pCached = HostCache.Gnutella2.Add(
					(IN_ADDR*)&nAddress, nPort, tSeen, strVendor );
				
				if ( pCached != NULL && m_nNodeType == ntHub )
				{
					if ( pCached->m_nKeyValue == 0 ||
						 pCached->m_nKeyHost != Network.m_pHost.sin_addr.S_un.S_addr )
					{
						pCached->SetKey( nKey, &m_pHost.sin_addr );
					}
				}
				
				if ( strcmp( szType, "NH" ) == 0 )
				{
					m_pHubGroup->Add( (IN_ADDR*)&nAddress, nPort );
				}
			}
		}
		else if ( strcmp( szType, "TS" ) == 0 && nLength >= 4 )
		{
			m_tAdjust = (LONG)tNow - (LONG)pPacket->ReadLongBE();
		}

		pPacket->m_nPosition = nNext;
	}

	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour HUB ADVERTISEMENT WALKER : send

void CG2Neighbour::SendHAW()
{
	m_tLastHAW = GetTickCount();
	
	if ( m_nNodeType == ntLeaf || Neighbours.IsLeaf() ) return;
	
	CG2Packet* pPacket = CG2Packet::New( G2_PACKET_HAW, TRUE );
	
	WORD nLeafs = 0;
	GGUID pGUID;
	
	Network.CreateID( &pGUID );
	
	for ( POSITION pos = Neighbours.GetIterator() ; pos ; )
	{
		CNeighbour* pNeighbour = Neighbours.GetNext( pos );
		
		if (	pNeighbour != this &&
				pNeighbour->m_nState == nrsConnected &&
				pNeighbour->m_nNodeType == ntLeaf )
		{
			nLeafs++;
		}
	}
	
	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( nLeafs );
	
	pPacket->WritePacket( "V", 4 );
	pPacket->WriteString( SHAREAZA_VENDOR_A );	// 5 bytes
	
	pPacket->WriteByte( 100 );
	pPacket->WriteByte( 0 );
	pPacket->Write( &pGUID, sizeof(GGUID) );
	
	Send( pPacket, TRUE, TRUE );
	
	m_pGUIDCache->Add( &pGUID, this );
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour HUB ADVERTISEMENT WALKER : receive

BOOL CG2Neighbour::OnHAW(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	
	CString strVendor;
	CHAR szType[9];
	DWORD nLength;
	
	DWORD nAddress	= 0;
	WORD nPort		= 0;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nNext = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "V" ) == 0 && nLength >= 4 )
		{
			strVendor = pPacket->ReadString( 4 );
		}
		else if ( strcmp( szType, "NA" ) == 0 && nLength >= 6 )
		{
			nAddress	= pPacket->ReadLongLE();
			nPort		= pPacket->ReadShortBE();
		}
		
		pPacket->m_nPosition = nNext;
	}
	
	if ( pPacket->GetRemaining() < 2 + 16 ) return TRUE;
	if ( nAddress == 0 || nPort == 0 ) return TRUE;
	if ( Network.IsFirewalledAddress( &nAddress, TRUE ) ) return TRUE;

	BYTE* pPtr	= pPacket->m_pBuffer + pPacket->m_nPosition;
	BYTE nTTL	= pPacket->ReadByte();
	BYTE nHops	= pPacket->ReadByte();

	GGUID pGUID;
	pPacket->Read( &pGUID, sizeof(GGUID) );

	HostCache.Gnutella2.Add( (IN_ADDR*)&nAddress, nPort, 0, strVendor );

	if ( nTTL > 0 && nHops < 255 )
	{
		m_pGUIDCache->Add( &pGUID, this );

		pPtr[0] = nTTL  - 1;
		pPtr[1] = nHops + 1;

		if ( CG2Neighbour* pNeighbour = Neighbours.GetRandomHub( this, &pGUID ) )
		{
			pNeighbour->Send( pPacket, FALSE, TRUE );
		}
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour QUERY packet handler

BOOL CG2Neighbour::SendQuery(CQuerySearch* pSearch, CPacket* pPacket, BOOL bLocal)
{
	if ( m_nState != nrsConnected )
	{
		return FALSE;
	}
	else if ( pPacket == NULL || pPacket->m_nProtocol != PROTOCOL_G2 )
	{
		return FALSE;
	}
	else if ( m_nNodeType == ntHub && ! bLocal )
	{
		return FALSE;
	}
	else if ( m_pQueryTableRemote != NULL && m_pQueryTableRemote->m_bLive && ( m_nNodeType == ntLeaf || pSearch->m_bUDP ) )
	{
		if ( ! m_pQueryTableRemote->Check( pSearch ) ) return FALSE;
	}
	else if ( m_nNodeType == ntLeaf && ! bLocal )
	{
		return FALSE;
	}
	
	Send( pPacket, FALSE, ! bLocal );
	
	return TRUE;
}

BOOL CG2Neighbour::OnQuery(CG2Packet* pPacket)
{
	CQuerySearch* pSearch = CQuerySearch::FromPacket( pPacket );

	if ( pSearch == NULL )
	{
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_QUERY, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella2.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	
	if ( m_nNodeType == ntLeaf && pSearch->m_bUDP &&
		 pSearch->m_pEndpoint.sin_addr.S_un.S_addr != m_pHost.sin_addr.S_un.S_addr )
	{
		delete pSearch;
		Statistics.Current.Gnutella2.Dropped++;
		m_nDropCount++;
		return TRUE;
	}

	if ( ! Network.QueryRoute->Add( &pSearch->m_pGUID, this ) )
	{
		delete pSearch;
		Statistics.Current.Gnutella2.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	
	if ( m_nNodeType != ntHub )
	{
		if ( pPacket->IsType( G2_PACKET_QUERY_WRAP ) )
		{
			if ( ! pPacket->SeekToWrapped() ) return TRUE;
			GNUTELLAPACKET* pG1 = (GNUTELLAPACKET*)( pPacket->m_pBuffer + pPacket->m_nPosition );
			
			if ( pG1->m_nTTL > 1 )
			{
				pG1->m_nTTL--;
				pG1->m_nHops++;
				Neighbours.RouteQuery( pSearch, pPacket, this, TRUE );
			}
		}
		else
		{
			Neighbours.RouteQuery( pSearch, pPacket, this, m_nNodeType == ntLeaf );
		}
	}
	
	Network.OnQuerySearch( pSearch );
	
	if ( pSearch->m_bUDP && /* Network.IsStable() && Datagrams.IsStable() && */
		 pSearch->m_pEndpoint.sin_addr.S_un.S_addr != m_pHost.sin_addr.S_un.S_addr )
	{
		CLocalSearch pLocal( pSearch, &pSearch->m_pEndpoint );
		pLocal.Execute();
	}
	else
	{
		BOOL bIsG1 = pPacket->IsType( G2_PACKET_QUERY_WRAP );
		
		if ( ! bIsG1 || Settings.Gnutella1.EnableToday )
		{
			CLocalSearch pLocal( pSearch, this, bIsG1 );
			pLocal.Execute();
		}
	}
	
	if ( m_nNodeType == ntLeaf ) Send( Neighbours.CreateQueryWeb( &pSearch->m_pGUID, this ), TRUE, FALSE );
	
	delete pSearch;
	Statistics.Current.Gnutella2.Queries++;
	
	return TRUE;
}

BOOL CG2Neighbour::OnQueryAck(CG2Packet* pPacket)
{
	HostCache.Gnutella2.Add( &m_pHost.sin_addr, htons( m_pHost.sin_port ) );
	SearchManager.OnQueryAck( pPacket, &m_pHost, NULL );
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour QUERY KEY REQUEST packet handler

BOOL CG2Neighbour::OnQueryKeyReq(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	if ( m_nNodeType != ntLeaf ) return TRUE;
	
	DWORD nLength, nAddress = 0;
	BOOL bCacheOkay = TRUE;
	CHAR szType[9];
	WORD nPort = 0;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nOffset = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "QNA" ) == 0 && nLength >= 6 )
		{
			nAddress	= pPacket->ReadLongLE();
			nPort		= pPacket->ReadShortBE();
		}
		else if ( strcmp( szType, "REF" ) == 0 )
		{
			bCacheOkay = FALSE;
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	if ( Network.IsFirewalledAddress( &nAddress, TRUE ) || 0 == nPort ) return TRUE;
	
	CHostCacheHost* pCached = bCacheOkay ? HostCache.Gnutella2.Find( (IN_ADDR*)&nAddress ) : NULL;
	
	if ( pCached != NULL && pCached->m_nKeyValue != 0 &&
		 pCached->m_nKeyHost == Network.m_pHost.sin_addr.S_un.S_addr )
	{
		CG2Packet* pAnswer = CG2Packet::New( G2_PACKET_QUERY_KEY_ANS, TRUE );
		pAnswer->WritePacket( "QNA", 6 );
		pAnswer->WriteLongLE( nAddress );
		pAnswer->WriteShortBE( nPort );
		pAnswer->WritePacket( "QK", 4 );
		pAnswer->WriteLongBE( pCached->m_nKeyValue );
		pAnswer->WritePacket( "CACHED", 0 );
		Send( pAnswer );
	}
	else
	{
		CG2Packet* pRequest = CG2Packet::New( G2_PACKET_QUERY_KEY_REQ, TRUE );
		pRequest->WritePacket( "SNA", 4 );
		pRequest->WriteLongLE( m_pHost.sin_addr.S_un.S_addr );
		Datagrams.Send( (IN_ADDR*)&nAddress, nPort, pRequest, TRUE, NULL, FALSE );
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour QUERY KEY ANSWER packet handler

BOOL CG2Neighbour::OnQueryKeyAns(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	if ( m_nNodeType != ntHub ) return TRUE;
	
	DWORD nKey = 0, nAddress = 0;
	WORD nPort = 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, "QNA" ) == 0 && nLength >= 6 )
		{
			nAddress	= pPacket->ReadLongLE();
			nPort		= pPacket->ReadShortBE();
		}
		else if ( strcmp( szType, "CACHED" ) == 0 )
		{
			m_bCachedKeys = TRUE;
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	theApp.Message( MSG_DEBUG, _T("Got a query key for %s:%i via neighbour %s: 0x%x"),
		(LPCTSTR)CString( inet_ntoa( *(IN_ADDR*)&nAddress ) ), nPort, (LPCTSTR)m_sAddress, nKey );
	
	if ( Network.IsFirewalledAddress( &nAddress ) || 0 == nPort ) return TRUE;
	
	CHostCacheHost* pCache = HostCache.Gnutella2.Add( (IN_ADDR*)&nAddress, nPort );
	if ( pCache != NULL ) pCache->SetKey( nKey, &m_pHost.sin_addr );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour PUSH packet handler

BOOL CG2Neighbour::OnPush(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;

	DWORD nLength = pPacket->GetRemaining();

	if ( ! pPacket->SkipCompound( nLength, 6 ) )
	{
		pPacket->Debug( _T("BadPush") );
		Statistics.Current.Gnutella2.Dropped++;
		return TRUE;
	}
	
	DWORD nAddress	= pPacket->ReadLongLE();
	WORD nPort		= pPacket->ReadShortBE();
	
	if ( Security.IsDenied( (IN_ADDR*)&nAddress ) )
	{
		Statistics.Current.Gnutella2.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	else if ( ! nPort || Network.IsFirewalledAddress( &nAddress ) )
	{
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_ZERO_PUSH, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella2.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	
	Handshakes.PushTo( (IN_ADDR*)&nAddress, nPort );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour USER PROFILE CHALLENGE packet handler

BOOL CG2Neighbour::OnProfileChallenge(CG2Packet* pPacket)
{
	if ( ! MyProfile.IsValid() ) return TRUE;
	
	CG2Packet* pProfile = CG2Packet::New( G2_PACKET_PROFILE_DELIVERY, TRUE );
	
	CString strXML = MyProfile.GetXML( NULL, TRUE )->ToString( TRUE );
	
	pProfile->WritePacket( "XML", pProfile->GetStringLen( strXML ) );
	pProfile->WriteString( strXML, FALSE );
	
	Send( pProfile, TRUE, TRUE );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG2Neighbour USER PROFILE DELIVERY packet handler

BOOL CG2Neighbour::OnProfileDelivery(CG2Packet* pPacket)
{
	if ( ! pPacket->m_bCompound ) return TRUE;
	
	CHAR szType[9];
	DWORD nLength;
	
	while ( pPacket->ReadPacket( szType, nLength ) )
	{
		DWORD nOffset = pPacket->m_nPosition + nLength;
		
		if ( strcmp( szType, "XML" ) == 0 )
		{
			CXMLElement* pXML = CXMLElement::FromString( pPacket->ReadString( nLength ), TRUE );
			
			if ( pXML )
			{
				if ( m_pProfile == NULL ) m_pProfile = new CGProfile();
				if ( ! m_pProfile->FromXML( pXML ) ) delete pXML;
			}
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	return TRUE;
}

⌨️ 快捷键说明

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