📄 network.cpp
字号:
{
CopyMemory( &pHost->sin_addr, &dwIP, 4 );
}
return TRUE;
}
BOOL CNetwork::AsyncResolve(LPCTSTR pszAddress, WORD nPort, PROTOCOLID nProtocol, BYTE nCommand)
{
CSingleLock pLock( &m_pSection );
if ( ! pLock.Lock( 250 ) ) return FALSE;
BYTE* pResolve = (BYTE*)malloc( MAXGETHOSTSTRUCT + 8 );
USES_CONVERSION;
HANDLE hAsync = WSAAsyncGetHostByName( AfxGetMainWnd()->GetSafeHwnd(), WM_WINSOCK,
T2CA(pszAddress), (LPSTR)pResolve + 8, MAXGETHOSTSTRUCT );
if ( hAsync != NULL )
{
*((CString**)&pResolve[0]) = new CString( pszAddress );
*((WORD*)&pResolve[4]) = nPort;
*((BYTE*)&pResolve[6]) = nProtocol;
*((BYTE*)&pResolve[7]) = nCommand;
m_pLookups.SetAt( (LPVOID)hAsync, (LPVOID)pResolve );
return TRUE;
}
else
{
free( pResolve );
return FALSE;
}
}
WORD CNetwork::RandomPort() const
{
return 10000 + ( rand() % 50000 );
}
//////////////////////////////////////////////////////////////////////
// CNetwork thread run
UINT CNetwork::ThreadStart(LPVOID pParam)
{
CNetwork* pNetwork = (CNetwork*)pParam;
pNetwork->OnRun();
return 0;
}
void CNetwork::OnRun()
{
while ( m_bEnabled )
{
Sleep( 50 );
WaitForSingleObject( m_pWakeup, 100 );
if ( m_bEnabled && m_pSection.Lock() )
{
Datagrams.OnRun();
SearchManager.OnRun();
QueryHashMaster.Build();
if ( CrawlSession.m_bActive ) CrawlSession.OnRun();
m_pSection.Unlock();
}
Neighbours.OnRun();
}
}
//////////////////////////////////////////////////////////////////////
// CNetwork resolve callback
void CNetwork::OnWinsock(WPARAM wParam, LPARAM lParam)
{
CSingleLock pLock( &m_pSection, TRUE );
LPBYTE pBuffer = NULL;
if ( ! m_pLookups.Lookup( (LPVOID)wParam, (LPVOID&)pBuffer ) ) return;
m_pLookups.RemoveKey( (LPVOID)wParam );
CString* psHost = *(CString**)pBuffer;
WORD nPort = *(WORD*)(pBuffer + 4);
BYTE nProtocol = *(BYTE*)(pBuffer + 6);
BYTE nCommand = *(BYTE*)(pBuffer + 7);
HOSTENT* pHost = (HOSTENT*)(pBuffer + 8);
if ( WSAGETASYNCERROR(lParam) == 0 )
{
if ( nCommand == 0 )
{
HostCache.ForProtocol( nProtocol )->Add( (IN_ADDR*)pHost->h_addr, nPort );
}
else
{
Neighbours.ConnectTo( (IN_ADDR*)pHost->h_addr, nPort, nProtocol, FALSE, nCommand == 2 );
}
}
else if ( nCommand > 0 )
{
theApp.Message( MSG_ERROR, IDS_NETWORK_RESOLVE_FAIL, (LPCTSTR)*psHost );
}
delete psHost;
free( pBuffer );
}
//////////////////////////////////////////////////////////////////////
// CNetwork get node route
BOOL CNetwork::GetNodeRoute(GGUID* pGUID, CNeighbour** ppNeighbour, SOCKADDR_IN* pEndpoint)
{
if ( *pGUID == MyProfile.GUID ) return FALSE;
if ( Network.NodeRoute->Lookup( pGUID, ppNeighbour, pEndpoint ) ) return TRUE;
if ( ppNeighbour == NULL ) return FALSE;
for ( POSITION pos = Neighbours.GetIterator() ; pos ; )
{
CNeighbour* pNeighbour = Neighbours.GetNext( pos );
if ( pNeighbour->m_bGUID && pNeighbour->m_pGUID == *pGUID )
{
*ppNeighbour = pNeighbour;
return TRUE;
}
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CNetwork route generic packets
BOOL CNetwork::RoutePacket(CG2Packet* pPacket)
{
GGUID pGUID;
if ( ! pPacket->GetTo( &pGUID ) || pGUID == MyProfile.GUID ) return FALSE;
CNeighbour* pOrigin = NULL;
SOCKADDR_IN pEndpoint;
if ( GetNodeRoute( &pGUID, &pOrigin, &pEndpoint ) )
{
if ( pOrigin != NULL )
{
if ( pOrigin->m_nProtocol == PROTOCOL_G1 &&
pPacket->IsType( G2_PACKET_PUSH ) )
{
CG1Neighbour* pG1 = (CG1Neighbour*)pOrigin;
pPacket->SkipCompound();
pG1->SendG2Push( &pGUID, pPacket );
}
else
{
pOrigin->Send( pPacket, FALSE, TRUE );
}
}
else
{
Datagrams.Send( &pEndpoint, pPacket, FALSE );
}
Statistics.Current.Gnutella2.Routed++;
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CNetwork send a push request
BOOL CNetwork::SendPush(GGUID* pGUID, DWORD nIndex)
{
CSingleLock pLock( &Network.m_pSection );
if ( ! pLock.Lock( 250 ) ) return TRUE;
if ( ! IsListening() ) return FALSE;
GGUID pGUID2 = *pGUID;
SOCKADDR_IN pEndpoint;
CNeighbour* pOrigin;
int nCount = 0;
while ( GetNodeRoute( &pGUID2, &pOrigin, &pEndpoint ) )
{
if ( pOrigin != NULL && pOrigin->m_nProtocol == PROTOCOL_G1 )
{
CG1Packet* pPacket = CG1Packet::New( G1_PACKET_PUSH,
Settings.Gnutella1.MaximumTTL - 1 );
pPacket->Write( pGUID, 16 );
pPacket->WriteLongLE( nIndex );
pPacket->WriteLongLE( m_pHost.sin_addr.S_un.S_addr );
pPacket->WriteShortLE( htons( m_pHost.sin_port ) );
pOrigin->Send( pPacket );
}
else
{
CG2Packet* pPacket = CG2Packet::New( G2_PACKET_PUSH, TRUE );
pPacket->WritePacket( G2_PACKET_TO, 16 );
pPacket->Write( pGUID, 16 );
pPacket->WriteByte( 0 );
pPacket->WriteLongLE( m_pHost.sin_addr.S_un.S_addr );
pPacket->WriteShortBE( htons( m_pHost.sin_port ) );
if ( pOrigin != NULL )
{
pOrigin->Send( pPacket );
}
else
{
Datagrams.Send( &pEndpoint, pPacket );
}
}
pGUID2.n[15] ++;
nCount++;
}
return nCount > 0;
}
//////////////////////////////////////////////////////////////////////
// CNetwork hit routing
BOOL CNetwork::RouteHits(CQueryHit* pHits, CPacket* pPacket)
{
SOCKADDR_IN pEndpoint;
CNeighbour* pOrigin;
if ( ! QueryRoute->Lookup( &pHits->m_pSearchID, &pOrigin, &pEndpoint ) ) return FALSE;
BOOL bWrapped = FALSE;
if ( pPacket->m_nProtocol == PROTOCOL_G1 )
{
CG1Packet* pG1 = (CG1Packet*)pPacket;
if ( ! pG1->Hop() ) return FALSE;
}
else if ( pPacket->m_nProtocol == PROTOCOL_G2 )
{
CG2Packet* pG2 = (CG2Packet*)pPacket;
if ( pG2->IsType( G2_PACKET_HIT ) && pG2->m_nLength > 17 )
{
BYTE* pHops = pG2->m_pBuffer + pG2->m_nLength - 17;
if ( *pHops > Settings.Gnutella1.MaximumTTL ) return FALSE;
(*pHops) ++;
}
else if ( pG2->IsType( G2_PACKET_HIT_WRAP ) )
{
if ( ! pG2->SeekToWrapped() ) return FALSE;
GNUTELLAPACKET* pG1 = (GNUTELLAPACKET*)( pPacket->m_pBuffer + pPacket->m_nPosition );
if ( pG1->m_nTTL == 0 ) return FALSE;
pG1->m_nTTL --;
pG1->m_nHops ++;
bWrapped = TRUE;
}
}
if ( pOrigin != NULL )
{
if ( pOrigin->m_nProtocol == pPacket->m_nProtocol )
{
pOrigin->Send( pPacket, FALSE, FALSE ); // Dont buffer
}
else if ( pOrigin->m_nProtocol == PROTOCOL_G1 && pPacket->m_nProtocol == PROTOCOL_G2 )
{
if ( ! bWrapped ) return FALSE;
pPacket = CG1Packet::New( (GNUTELLAPACKET*)( pPacket->m_pBuffer + pPacket->m_nPosition ) );
pOrigin->Send( pPacket, TRUE, TRUE );
}
else if ( pOrigin->m_nProtocol == PROTOCOL_G2 && pPacket->m_nProtocol == PROTOCOL_G1 )
{
pPacket = CG2Packet::New( G2_PACKET_HIT_WRAP, (CG1Packet*)pPacket );
pOrigin->Send( pPacket, TRUE, FALSE ); // Dont buffer
}
else
{
// Should not happen either (logic flaw)
return FALSE;
}
}
else if ( pPacket->m_nProtocol == PROTOCOL_G2 )
{
if ( pEndpoint.sin_addr.S_un.S_addr == Network.m_pHost.sin_addr.S_un.S_addr ) return FALSE;
Datagrams.Send( &pEndpoint, (CG2Packet*)pPacket, FALSE );
}
else
{
if ( pEndpoint.sin_addr.S_un.S_addr == Network.m_pHost.sin_addr.S_un.S_addr ) return FALSE;
pPacket = CG2Packet::New( G2_PACKET_HIT_WRAP, (CG1Packet*)pPacket );
Datagrams.Send( &pEndpoint, (CG2Packet*)pPacket, TRUE );
}
if ( pPacket->m_nProtocol == PROTOCOL_G1 )
Statistics.Current.Gnutella1.Routed++;
else if ( pPacket->m_nProtocol == PROTOCOL_G2 )
Statistics.Current.Gnutella2.Routed++;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CNetwork common handler functions
void CNetwork::OnQuerySearch(CQuerySearch* pSearch)
{
CSingleLock pLock( &theApp.m_pSection );
if ( pLock.Lock( 10 ) )
{
if ( CMainWnd* pMainWnd = theApp.SafeMainWnd() )
{
CWindowManager* pWindows = &pMainWnd->m_pWindows;
CChildWnd* pChildWnd = NULL;
CRuntimeClass* pClass = RUNTIME_CLASS(CSearchMonitorWnd);
while ( pChildWnd = pWindows->Find( pClass, pChildWnd ) )
{
pChildWnd->OnQuerySearch( pSearch );
}
}
pLock.Unlock();
}
}
void CNetwork::OnQueryHits(CQueryHit* pHits)
{
Downloads.OnQueryHits( pHits );
CSingleLock pLock( &theApp.m_pSection );
if ( pLock.Lock( 250 ) )
{
if ( CMainWnd* pMainWnd = theApp.SafeMainWnd() )
{
CWindowManager* pWindows = &pMainWnd->m_pWindows;
CChildWnd* pChildWnd = NULL;
CChildWnd* pMonitorWnd = NULL;
CRuntimeClass* pMonitorType = RUNTIME_CLASS(CHitMonitorWnd);
while ( pChildWnd = pWindows->Find( NULL, pChildWnd ) )
{
if ( pChildWnd->GetRuntimeClass() == pMonitorType )
{
pMonitorWnd = pChildWnd;
}
else
{
if ( pChildWnd->OnQueryHits( pHits ) ) return;
}
}
if ( pMonitorWnd != NULL )
{
if ( pMonitorWnd->OnQueryHits( pHits ) ) return;
}
}
pLock.Unlock();
}
pHits->Delete();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -