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

📄 g1neighbour.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if ( ! bLocal && ! Network.IsFirewalledAddress( &nAddress, TRUE ) )
	{
		if ( pPacket->m_nHops == 0 && nAddress == m_pHost.sin_addr.S_un.S_addr )
		{
			m_nFileCount	= nFiles;
			m_nFileVolume	= nVolume;

			HostCache.Gnutella1.Add( (IN_ADDR*)&nAddress, nPort, 0, m_bShareaza ? SHAREAZA_VENDOR_T : NULL );
		}
		else
		{
			HostCache.Gnutella1.Add( (IN_ADDR*)&nAddress, nPort );
		}
	}
	
	BYTE nHops = pPacket->m_nHops + 1;
	nHops = min( nHops, PONG_NEEDED_BUFFER - 1 );
	
	if ( ! bLocal ) Neighbours.OnG1Pong( this, (IN_ADDR*)&nAddress, nPort, nHops + 1, nFiles, nVolume );
	
	return TRUE;
}

void CG1Neighbour::OnNewPong(CPongItem* pPong)
{
	if ( m_nPongNeeded[ pPong->m_nHops ] > 0 )
	{
		Send( pPong->ToPacket( m_nLastPingHops, &m_pLastPingID ) );
		m_nPongNeeded[ pPong->m_nHops ] --;
	}
}

//////////////////////////////////////////////////////////////////////
// CG1Neighbour BYE packet handler

BOOL CG1Neighbour::OnBye(CG1Packet* pPacket)
{
	CString strReason;
	WORD nReason = 0;
	
	if ( pPacket->m_nLength >= 3 )
	{
		nReason		= pPacket->ReadShortLE();
		strReason	= pPacket->ReadString();
	}
	
	for ( int nChar = 0 ; nChar < strReason.GetLength() ; nChar++ )
	{
		if ( strReason[nChar] < 32 )
		{
			strReason = strReason.Left( nChar );
			break;
		}
	}

	if ( strReason.IsEmpty() || strReason.GetLength() > 128 ) strReason = _T("No Message");

	theApp.Message( MSG_ERROR, IDS_CONNECTION_BYE, (LPCTSTR)m_sAddress,
		nReason, (LPCTSTR)strReason );

	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CG1Neighbour VENDOR packet handler

BOOL CG1Neighbour::OnVendor(CG1Packet* pPacket)
{
	if ( pPacket->m_nLength < 8 || ! Settings.Gnutella1.VendorMsg )
	{
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return TRUE;
	}

	DWORD nVendor	= pPacket->ReadLongLE();
	WORD nFunction	= pPacket->ReadShortLE();
	WORD nVersion	= pPacket->ReadShortLE();
	
	if ( nVendor == 0 && nFunction == 0 )
	{
		// Supported vendor messages array
	}
	else if ( nFunction == 0xFFFF )
	{
		if ( nVendor == 0 )
		{
			// Vendor code query
			CG1Packet* pReply = CG1Packet::New( pPacket->m_nType, 1, &pPacket->m_pGUID );
			pReply->WriteLongLE( 0 );
			pReply->WriteShortLE( 0xFFFE );
			pReply->WriteShortLE( 1 );
			pReply->WriteLongLE( 'AZAR' );
			pReply->WriteLongLE( 'RAEB' );
			Send( pReply );
		}
		else if ( nVendor == 'AZAR' )
		{
			// Function code query for "RAZA"
			CG1Packet* pReply = CG1Packet::New( pPacket->m_nType, 1, &pPacket->m_pGUID );
			pReply->WriteLongLE( 'AZAR' );
			pReply->WriteShortLE( 0xFFFE );
			pReply->WriteShortLE( 1 );
			pReply->WriteShortLE( 0x0001 );
			pReply->WriteShortLE( 1 );
			pReply->WriteShortLE( 0x0002 );
			pReply->WriteShortLE( 1 );
			pReply->WriteShortLE( 0x0003 );
			pReply->WriteShortLE( 1 );
			Send( pReply );
		}
		else if ( nVendor == 'RAEB' )
		{
			// Function code query for "BEAR"
			CG1Packet* pReply = CG1Packet::New( pPacket->m_nType, 1, &pPacket->m_pGUID );
			pReply->WriteLongLE( 'RAEB' );
			pReply->WriteShortLE( 0xFFFE );
			pReply->WriteShortLE( 1 );
			pReply->WriteShortLE( 0x0004 );
			pReply->WriteShortLE( 1 );
			pReply->WriteShortLE( 0x000B );
			pReply->WriteShortLE( 1 );
			pReply->WriteShortLE( 0x000C );
			pReply->WriteShortLE( 1 );
			Send( pReply );
		}
	}
	else if ( nVendor == 'AZAR' )
	{
		switch ( nFunction )
		{
		case 0x0001:
			// Version Query
			if ( nVersion <= 1 )
			{
				CG1Packet* pReply = CG1Packet::New( pPacket->m_nType, 1, &pPacket->m_pGUID );
				pReply->WriteLongLE( 'AZAR' );
				pReply->WriteShortLE( 0x0002 );
				pReply->WriteShortLE( 1 );
				pReply->WriteShortLE( theApp.m_nVersion[0] );
				pReply->WriteShortLE( theApp.m_nVersion[1] );
				pReply->WriteShortLE( theApp.m_nVersion[2] );
				pReply->WriteShortLE( theApp.m_nVersion[3] );
				Send( pReply );
			}
			break;
		case 0x0002:
			// Version Response
			if ( nVersion <= 1 && pPacket->GetRemaining() >= 8 )
			{
				WORD nVersion[4];
				nVersion[0] = pPacket->ReadShortLE();
				nVersion[1] = pPacket->ReadShortLE();
				nVersion[2] = pPacket->ReadShortLE();
				nVersion[3] = pPacket->ReadShortLE();
			}
			break;
		case 0x0003:
			// Cluster Advisor
			if ( nVersion <= 1 && pPacket->GetRemaining() >= 28 )
			{
				OnClusterAdvisor( pPacket );
			}
			break;
		}
	}
	else if ( nVendor == 'RAEB' )
	{
		switch ( nFunction )
		{
		case 0x0001:
			// Super Pong
			// (WORD)Count, [ (DWORD)IP, (WORD)Port ], SIG
			break;
		case 0x0003:
			// Product Identifiers
			break;
		case 0x0004:
			// Hops Flow
			if ( nVersion <= 1 && pPacket->GetRemaining() >= 1 ) 
			{
				m_nHopsFlow = pPacket->ReadByte();
			}
			break;
		case 0x0005:
			// Horizon Ping
			// (BYTE)TTL
			break;
		case 0x0006:
			// Horizon Pong
			// (BYTE)maxTTL, (DWORD)sharing, (DWORD)freepeers, (DWORD)auth'ed
			break;
		case 0x000B:
			// Query Status Request
			if ( nVersion <= 1 )
			{
				CG1Packet* pReply = CG1Packet::New( pPacket->m_nType, 1, &pPacket->m_pGUID );
				pReply->WriteLongLE( 'RAEB' );
				pReply->WriteShortLE( 0x000C );
				pReply->WriteShortLE( 1 );
				pReply->WriteShortLE( SearchManager.OnQueryStatusRequest( &pPacket->m_pGUID ) );
				Send( pReply );
			}
			break;
		case 0x000C:
			// Query Status Response
			// (WORD)hit_count
			break;
		}
	}

	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG1Neighbour VENDOR cluster handlers

void CG1Neighbour::SendClusterAdvisor()
{
	if ( ! m_bShareaza || ! Settings.Gnutella1.VendorMsg ) return;

	DWORD tNow = time( NULL );
	CG1Packet* pPacket = NULL;
	WORD nCount = 0;

	for ( CHostCacheHost* pHost = HostCache.Gnutella1.GetNewest() ; pHost && nCount < 20 ; pHost = pHost->m_pPrevTime )
	{
		if ( pHost->m_pVendor == VendorCache.m_pShareaza &&
			 pHost->m_tAdded > m_tClusterHost &&
			 pHost->CanConnect( tNow ) )
		{
			if ( ! pPacket )
			{
				pPacket = CG1Packet::New( G1_PACKET_VENDOR, 1 );
				pPacket->WriteLongLE( 'AZAR' );
				pPacket->WriteShortLE( 0x0003 );
				pPacket->WriteShortLE( 1 );
				pPacket->WriteShortLE( 0 );
			}
			pPacket->WriteLongLE( pHost->m_pAddress.S_un.S_addr );
			pPacket->WriteShortLE( pHost->m_nPort );
			nCount++;
		}
	}
	
	m_tClusterHost = GetTickCount();
	
	if ( pPacket && nCount )
	{
		m_tClusterSent = m_tClusterHost;
		((WORD*)pPacket->m_pBuffer)[4] = nCount;
		pPacket->RazaSign();
		Send( pPacket, TRUE, TRUE );
	}
}

BOOL CG1Neighbour::OnClusterAdvisor(CG1Packet* pPacket)
{
	if ( ! pPacket->RazaVerify() ) return FALSE;
	
	WORD nCount = pPacket->ReadShortLE();
	if ( pPacket->GetRemaining() < nCount * 6 + 20 ) return FALSE;
	
	SendClusterAdvisor();
	
	while ( nCount-- )
	{
		DWORD nAddress	= pPacket->ReadLongLE();
		WORD nPort		= pPacket->ReadShortLE();
		HostCache.Gnutella1.Add( (IN_ADDR*)&nAddress, nPort, 0, SHAREAZA_VENDOR_T );
	}
	
	m_tClusterHost = GetTickCount();
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG1Neighbour PUSH packet handler

BOOL CG1Neighbour::OnPush(CG1Packet* pPacket)
{
	if ( pPacket->m_nLength < 26 || ( pPacket->m_nLength > 26 && Settings.Gnutella1.StrictPackets ) )
	{
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_SIZE_PUSH, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	
	GGUID pClientID;
	pPacket->Read( &pClientID, 16 );
	DWORD nFileIndex	= pPacket->ReadLongLE();
	DWORD nAddress		= pPacket->ReadLongLE();
	WORD nPort			= pPacket->ReadShortLE();
	BOOL bGGEP			= FALSE;
	
	if ( Security.IsDenied( (IN_ADDR*)&nAddress ) )
	{
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	
	if ( pPacket->m_nLength > 26 && m_bGGEP )
	{
		if ( pPacket->ReadByte() != GGEP_MAGIC )
		{
			theApp.Message( MSG_ERROR, IDS_PROTOCOL_GGEP_REQUIRED, (LPCTSTR)m_sAddress );
			Statistics.Current.Gnutella1.Dropped++;
			m_nDropCount++;
			return TRUE;
		}
		bGGEP = TRUE;
	}
	
	if ( ! nPort || Network.IsFirewalledAddress( &nAddress ) )
	{
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_ZERO_PUSH, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	
	if ( pClientID == MyProfile.GUID )
	{
		Handshakes.PushTo( (IN_ADDR*)&nAddress, nPort, nFileIndex );
		return TRUE;
	}
	
	CNeighbour* pOrigin;
	
	Network.NodeRoute->Lookup( &pClientID, (CNeighbour**)&pOrigin );
	
	if ( pOrigin && pPacket->Hop() )
	{
		if ( pOrigin->m_nProtocol == PROTOCOL_G1 )
		{
			if ( bGGEP && ! pOrigin->m_bGGEP ) pPacket->Shorten( 26 );
			pOrigin->Send( pPacket, FALSE, TRUE );
		}
		else if ( pOrigin->m_nProtocol == PROTOCOL_G2 )
		{
			CG2Packet* pWrap = CG2Packet::New( G2_PACKET_PUSH, TRUE );
			pWrap->WritePacket( "TO", 16 );
			pWrap->Write( &pClientID, 16 );
			pWrap->WriteByte( 0 );
			pWrap->WriteLongLE( nAddress );
			pWrap->WriteShortLE( nPort );
			pOrigin->Send( pWrap, TRUE, TRUE );
		}
		Statistics.Current.Gnutella1.Routed++;
	}
	
	return TRUE;
}

void CG1Neighbour::SendG2Push(GGUID* pGUID, CPacket* pPacket)
{
	if ( pPacket->GetRemaining() < 6 ) return;
	
	DWORD nAddress	= pPacket->ReadLongLE();
	WORD nPort		= pPacket->ReadShortLE();
	
	pPacket = CG1Packet::New( G1_PACKET_PUSH, Settings.Gnutella1.MaximumTTL - 1 );

	pPacket->Write( pGUID, 16 );
	pPacket->WriteLongLE( 0 );
	pPacket->WriteLongLE( nAddress );
	pPacket->WriteShortLE( nPort );
	
	Send( pPacket, TRUE, TRUE );
}

//////////////////////////////////////////////////////////////////////
// CG1Neighbour QUERY packet handlers

BOOL CG1Neighbour::OnQuery(CG1Packet* pPacket)
{
	if ( pPacket->m_nLength <= 5 )
	{
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_QUERY, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	else if ( pPacket->m_nLength > Settings.Gnutella1.MaximumQuery )
	{
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_TOO_LARGE, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return FALSE;
	}

	if ( m_nNodeType == ntLeaf && pPacket->m_nHops > 0 )
	{
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_LEAF_FORWARD, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return FALSE;
	}

	if ( ! Network.QueryRoute->Add( &pPacket->m_pGUID, this ) )
	{
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return TRUE;
	}

	CQuerySearch* pSearch = CQuerySearch::FromPacket( pPacket );

	if ( pSearch == NULL )
	{
		pPacket->Debug( _T("BadQuery") );
		theApp.Message( MSG_DEBUG, IDS_PROTOCOL_BAD_QUERY, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return TRUE;
	}
	
	CLocalSearch pLocalSearch( pSearch, this );

	if ( m_nNodeType != ntHub && pPacket->Hop() )
	{
		Neighbours.RouteQuery( pSearch, pPacket, this, TRUE );
	}
	
	Network.OnQuerySearch( pSearch );
	
	if ( ! pSearch->m_bFirewall || Network.IsListening() ) pLocalSearch.Execute();
	
	delete pSearch;
	
	Statistics.Current.Gnutella1.Queries++;
	
	return TRUE;
}

BOOL CG1Neighbour::SendQuery(CQuerySearch* pSearch, CPacket* pPacket, BOOL bLocal)
{
	if ( m_nState != nrsConnected ) return FALSE;
	if ( pPacket == NULL || pPacket->m_nProtocol != PROTOCOL_G1 ) return FALSE;

	CG1Packet* pG1 = (CG1Packet*)pPacket;

	if ( pG1->m_nHops > m_nHopsFlow )
	{
		return FALSE;
	}
	else if ( m_nNodeType == ntHub && ! bLocal )
	{
		return FALSE;
	}
	else if ( ! pSearch->m_bAndG1 )
	{
		return FALSE;
	}
	else if ( m_pQueryTableRemote != NULL && m_pQueryTableRemote->m_bLive )
	{
		if ( ! m_pQueryTableRemote->Check( pSearch ) ) return FALSE;
	}
	else if ( m_nNodeType == ntLeaf && ! bLocal )
	{
		return FALSE;
	}
	
	if ( bLocal ) m_tLastQuery = time( NULL );

	Send( pPacket, FALSE, ! bLocal );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CG1Neighbour QUERY HIT packet handler

BOOL CG1Neighbour::OnHit(CG1Packet* pPacket)
{
	if ( pPacket->m_nLength <= 27 )
	{
		theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_HIT, (LPCTSTR)m_sAddress );
		Statistics.Current.Gnutella1.Dropped++;
		m_nDropCount++;
		return TRUE;
	}

	return OnCommonHit( pPacket );
}

⌨️ 快捷键说明

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