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