📄 g1neighbour.cpp
字号:
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 + -