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; }
BOOL CHostBrowser::StreamPacketsG1() { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_nProtocol == PROTOCOL_G1 ); BOOL bSuccess = TRUE; for ( ; bSuccess; ) { GNUTELLAPACKET* pPacket = (GNUTELLAPACKET*)m_pBuffer->m_pBuffer; if ( m_pBuffer->m_nLength < sizeof( *pPacket ) ) break; DWORD nLength = sizeof( *pPacket ) + pPacket->m_nLength; if ( pPacket->m_nLength < 0 || nLength >= (DWORD)Settings.Gnutella.MaximumPacket * 8 ) { theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress ); Stop(); return FALSE; } if ( m_pBuffer->m_nLength < nLength ) break; CG1Packet* pPacketObject = CG1Packet::New( pPacket ); try { bSuccess = OnPacket( pPacketObject ); } catch ( CException* pException ) { pException->Delete(); } pPacketObject->Release(); m_pBuffer->Remove( nLength ); } if ( ! bSuccess ) Stop(); return bSuccess; }
// Takes an expiration time, and access to 2 integers to write statistics // Gets the packet we added most recently that hasn't expired, and moves head forward and decrements count // Returns a pointer to it CG1Packet* CG1PacketBufferType::Get(DWORD dwExpire, int* pnTotal, int* pnDropped) { // Local variables CG1Packet* pPacket; // A pointer to a packet copied from the array of packet pointers DWORD dwPacket; // The expiration time of that packet // Loop until we find a packet that hasn't expired do { // If there aren't any packet pointers in the array, we won't be able to find this one if ( ! m_nCount ) return NULL; // Not found // Get the packet pointer and time we most recently added to the arrays pPacket = m_pBuffer[ m_nHead ]; // The pointer the Add method added the last time it ran dwPacket = m_pTime[ m_nHead ]; // The tick count 1 minute after it ran // Move forward in the array to the next most recently added packet m_nHead = ( m_nHead + 1 ) % m_nCapacity; // Add 1 to head unless it is 63, then take it back to 0 // This packet is either expired, or will be returned, so we can record 1 less packet in the array m_nCount--; // This packet has expired if ( dwPacket < dwExpire ) // This packet's expiration date happened before the given expiration date { // Adjust the numbers the caller gave us access to if ( pnTotal ) (*pnTotal)--; // This is one less packet total if ( pnDropped ) (*pnDropped)++; // This is one more packet dropped // Count this in statistics as a lost packet Statistics.Current.Gnutella1.Lost++; // Tell the packet we're no longer pointing to it from here pPacket->Release(); pPacket = NULL; // Stay in the do while loop } } while ( pPacket == NULL ); // If the if statement didn't run, exit the do while loop // Return the pointer to the first packet we found that hasn't expired return pPacket; }
CG1Packet* CLocalSearch::CreatePacketG1() { DWORD nTTL = m_bUDP ? 1 : ( m_pSearch ? ( m_pSearch->m_nHops + 2 ) : Settings.Gnutella1.SearchTTL ); CG1Packet* pPacket = CG1Packet::New( G1_PACKET_HIT, nTTL, m_oGUID ); pPacket->WriteByte( 0 ); // Hit count will be set latter pPacket->WriteShortLE( htons( Network.m_pHost.sin_port ) ); pPacket->WriteLongLE( Network.m_pHost.sin_addr.s_addr ); if ( Uploads.m_bStable ) { pPacket->WriteLongLE( Uploads.m_nBestSpeed * 8 / 1024 ); } else { pPacket->WriteLongLE( Settings.Connection.OutSpeed ); } return pPacket; }