BOOL CHostBrowser::StreamPacketsG2() { CG2Packet* pPacket; while ( pPacket = CG2Packet::ReadBuffer( m_pBuffer ) ) { BOOL bSuccess = FALSE; try { bSuccess = OnPacket( pPacket ); } catch ( CException* pException ) { pException->Delete(); } pPacket->Release(); if ( ! bSuccess ) { Stop(); return FALSE; } } return TRUE; }
void CLocalSearch::WriteTrailerG2() { CG2Packet* pPacket = (CG2Packet*)m_pPacket; pPacket->WriteByte( 0 ); pPacket->WriteByte( 0 ); pPacket->Write( &m_pGUID, sizeof(GGUID) ); }
void CCrawlSession::SendCrawl(SOCKADDR_IN* pHost) { theApp.Message( MSG_DEBUG, _T("CRAWL: Crawling host %s"), (LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ) ); CG2Packet* pPacket = CG2Packet::New( G2_PACKET_CRAWL_REQ, TRUE ); pPacket->WritePacket( G2_PACKET_CRAWL_RLEAF, 0 ); pPacket->WritePacket( G2_PACKET_CRAWL_RNAME, 0 ); pPacket->WritePacket( G2_PACKET_CRAWL_RGPS, 0 ); Datagrams.Send( pHost, pPacket ); }
CG2Packet* CLocalSearch::FoldersToPacket() { CG2Packet* pPacket = CG2Packet::New( "PF", TRUE ); for ( POSITION pos = LibraryFolders.GetFolderIterator() ; pos ; ) { if ( CG2Packet* pChild = FolderToPacket( LibraryFolders.GetNextFolder( pos ) ) ) { pPacket->WritePacket( pChild ); pChild->Release(); } } return pPacket; }
CG2Packet* CLocalSearch::FoldersToPacket() { CG2Packet* pPacket = CG2Packet::New( G2_PACKET_PHYSICAL_FOLDER, TRUE ); if ( ! pPacket ) return NULL; for ( POSITION pos = LibraryFolders.GetFolderIterator() ; pos ; ) { if ( CG2Packet* pChild = FolderToPacket( LibraryFolders.GetNextFolder( pos ) ) ) { pPacket->WritePacket( pChild ); pChild->Release(); } } return pPacket; }
CG2Packet* CG2Packet::New(G2_PACKET nType, CG1Packet* pWrap, int nMinTTL) { CG2Packet* pPacket = New( nType, FALSE ); GNUTELLAPACKET pHeader; pHeader.m_oGUID = pWrap->m_oGUID.storage(); pHeader.m_nType = pWrap->m_nType; pHeader.m_nTTL = min( pWrap->m_nTTL, BYTE(nMinTTL) ); pHeader.m_nHops = pWrap->m_nHops; pHeader.m_nLength = (LONG)pWrap->m_nLength; pPacket->Write( &pHeader, sizeof( pHeader ) ); pPacket->Write( pWrap->m_pBuffer, pWrap->m_nLength ); return pPacket; }
CG2Packet* CLocalSearch::FolderToPacket(CLibraryFolder* pFolder) { if ( pFolder == NULL ) return NULL; if ( pFolder->GetSharedCount( TRUE ) == 0 ) return NULL; CG2Packet* pPacket = CG2Packet::New( G2_PACKET_PHYSICAL_FOLDER, TRUE ); if ( ! pPacket ) return NULL; pPacket->WritePacket( G2_PACKET_DESCRIPTIVE_NAME, pPacket->GetStringLen( pFolder->m_sName ) ); pPacket->WriteString( pFolder->m_sName, FALSE ); for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; ) { if ( CG2Packet* pChild = FolderToPacket( pFolder->GetNextFolder( pos ) ) ) { pPacket->WritePacket( pChild ); pChild->Release(); } } if ( DWORD nFiles = pFolder->GetSharedCount( FALSE ) ) { pPacket->WritePacket( G2_PACKET_FILES, nFiles * 4u ); for ( POSITION pos = pFolder->GetFileIterator() ; pos ; ) { const CLibraryFile* pFile = pFolder->GetNextFile( pos ); if ( pFile->IsShared() ) pPacket->WriteLongBE( pFile->m_nIndex ); } } return pPacket; }
CG2Packet* CLocalSearch::FolderToPacket(CLibraryFolder* pFolder) { if ( pFolder == NULL ) return NULL; if ( pFolder->GetSharedCount() == 0 ) return NULL; CG2Packet* pPacket = CG2Packet::New( "PF", TRUE ); pPacket->WritePacket( "DN", pPacket->GetStringLen( pFolder->m_sName ) ); pPacket->WriteString( pFolder->m_sName, FALSE ); for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; ) { if ( CG2Packet* pChild = FolderToPacket( pFolder->GetNextFolder( pos ) ) ) { pPacket->WritePacket( pChild ); pChild->Release(); } } pPacket->WritePacket( "FILES", pFolder->GetFileCount() * 4 ); for ( POSITION pos = pFolder->GetFileIterator() ; pos ; ) { CLibraryFile* pFile = pFolder->GetNextFile( pos ); pPacket->WriteLongBE( pFile->m_nIndex ); } return pPacket; }
CG2Packet* CGProfile::CreateAvatar() const { const CXMLElement* pAvatar = m_pXML->GetElementByName( L"avatar" ); if ( pAvatar == NULL ) return NULL; CString strPath = pAvatar->GetAttributeValue( L"path" ); if ( strPath.IsEmpty() ) return NULL; CFile pFile; if ( ! pFile.Open( strPath, CFile::modeRead ) ) return NULL; int nPos = strPath.ReverseFind( L'\\' ); if ( nPos >= 0 ) strPath = strPath.Mid( nPos + 1 ); CG2Packet* pPacket = CG2Packet::New( G2_PACKET_PROFILE_AVATAR ); if ( ! pPacket ) return NULL; pPacket->WritePacket( G2_PACKET_NAME, pPacket->GetStringLen( strPath ) ); pPacket->WriteString( strPath, FALSE ); pPacket->WritePacket( G2_PACKET_BODY, (DWORD)pFile.GetLength() ); if ( LPBYTE pBody = pPacket->WriteGetPointer( (DWORD)pFile.GetLength() ) ) pFile.Read( pBody, (DWORD)pFile.GetLength() ); return pPacket; }
CG2Packet* CLocalSearch::AlbumToPacket(CAlbumFolder* pFolder) { if ( pFolder == NULL ) return NULL; if ( pFolder->m_pSchema != NULL && pFolder->m_pSchema->m_bPrivate ) return NULL; if ( pFolder->GetSharedCount( TRUE ) == 0 ) return NULL; CG2Packet* pPacket = CG2Packet::New( G2_PACKET_VIRTUAL_FOLDER, TRUE ); if ( ! pPacket ) return NULL; if ( pFolder->m_pSchema != NULL ) { auto_ptr< CXMLElement > pXML( pFolder->m_pSchema->Instantiate( TRUE ) ); if ( ! pXML.get() ) return NULL; if ( pFolder->m_pXML != NULL ) { pXML->AddElement( pFolder->m_pXML->Clone() ); } else { if ( CXMLElement* pBody = pXML->AddElement( pFolder->m_pSchema->m_sSingular ) ) { pBody->AddAttribute( pFolder->m_pSchema->GetFirstMemberName(), pFolder->m_sName ); } } CString strXML = pXML->ToString(); pPacket->WritePacket( G2_PACKET_METADATA, pPacket->GetStringLen( strXML ) ); pPacket->WriteString( strXML, FALSE ); } for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; ) { if ( CG2Packet* pChild = AlbumToPacket( pFolder->GetNextFolder( pos ) ) ) { pPacket->WritePacket( pChild ); pChild->Release(); } } if ( DWORD nFiles = pFolder->GetSharedCount( FALSE ) ) { pPacket->WritePacket( G2_PACKET_FILES, nFiles * 4u ); for ( POSITION pos = pFolder->GetFileIterator() ; pos ; ) { const CLibraryFile* pFile = pFolder->GetNextFile( pos ); if ( pFile->IsShared() ) pPacket->WriteLongBE( pFile->m_nIndex ); } } return pPacket; }
CG2Packet* CG2Packet::New(BYTE* pSource) { CG2Packet* pPacket = New(); BYTE nInput = *pSource++; BYTE nLenLen = ( nInput & 0xC0 ) >> 6; BYTE nTypeLen = ( nInput & 0x38 ) >> 3; BYTE nFlags = ( nInput & 0x07 ); pPacket->m_bCompound = ( nFlags & G2_FLAG_COMPOUND ) ? TRUE : FALSE; pPacket->m_bBigEndian = ( nFlags & G2_FLAG_BIG_ENDIAN ) ? TRUE : FALSE; DWORD nLength = 0; if ( pPacket->m_bBigEndian ) { for ( nLength = 0; nLenLen--; ) { nLength <<= 8; nLength |= *pSource++; } } else { BYTE* pLenOut = (BYTE*)&nLength; while ( nLenLen-- ) *pLenOut++ = *pSource++; } nTypeLen++; CopyMemory( &pPacket->m_nType, pSource, nTypeLen ); pSource += nTypeLen; pPacket->Write( pSource, nLength ); return pPacket; }
CG2Packet* CLocalSearch::AlbumToPacket(CAlbumFolder* pFolder) { if ( pFolder == NULL ) return NULL; if ( pFolder->m_pSchema != NULL && pFolder->m_pSchema->m_bPrivate ) return NULL; if ( pFolder->GetSharedCount() == 0 ) return NULL; CG2Packet* pPacket = CG2Packet::New( "VF", TRUE ); if ( pFolder->m_pSchema != NULL ) { CXMLElement* pXML = pFolder->m_pSchema->Instantiate( TRUE ); if ( pFolder->m_pXML != NULL ) { pXML->AddElement( pFolder->m_pXML->Clone() ); } else { CXMLElement* pBody = pXML->AddElement( pFolder->m_pSchema->m_sSingular ); pBody->AddAttribute( pFolder->m_pSchema->GetFirstMemberName(), pFolder->m_sName ); } CString strXML = pXML->ToString(); delete pXML; pPacket->WritePacket( "MD", pPacket->GetStringLen( strXML ) ); pPacket->WriteString( strXML, FALSE ); } for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; ) { if ( CG2Packet* pChild = AlbumToPacket( pFolder->GetNextFolder( pos ) ) ) { pPacket->WritePacket( pChild ); pChild->Release(); } } pPacket->WritePacket( "FILES", pFolder->GetFileCount() * 4 ); for ( POSITION pos = pFolder->GetFileIterator() ; pos ; ) { CLibraryFile* pFile = pFolder->GetNextFile( pos ); pPacket->WriteLongBE( pFile->m_nIndex ); } return pPacket; }
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; }
CG2Packet* CG2Packet::Clone() const { CG2Packet* pPacket = CG2Packet::New( m_nType, m_bCompound ); pPacket->Write( m_pBuffer, m_nLength ); return pPacket; }
void CLocalSearch::CreatePacketG2() { CG2Packet* pPacket = CG2Packet::New( G2_PACKET_HIT, TRUE ); m_pPacket = pPacket; pPacket->WritePacket( "GU", 16 ); GGUID tmp( MyProfile.GUID ); pPacket->Write( &tmp, sizeof(GGUID) ); if ( TRUE /* Network.IsListening() */ ) { 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( "V", 4 ); pPacket->WriteString( SHAREAZA_VENDOR_A, FALSE ); if ( ! Network.IsStable() || ! Datagrams.IsStable() ) { pPacket->WritePacket( "FW", 0 ); } { CSingleLock pNetLock( &Network.m_pSection ); if ( pNetLock.Lock( 50 ) ) { for ( POSITION pos = Neighbours.GetIterator() ; pos ; ) { CNeighbour* pNeighbour = Neighbours.GetNext( pos ); if ( pNeighbour->m_nNodeType != ntLeaf && pNeighbour->m_nProtocol == PROTOCOL_G2 ) { pPacket->WritePacket( "NH", 6 ); pPacket->WriteLongLE( pNeighbour->m_pHost.sin_addr.S_un.S_addr ); pPacket->WriteShortBE( htons( pNeighbour->m_pHost.sin_port ) ); } } } } if ( ! Uploads.m_bStable ) pPacket->WritePacket( "UNSTA", 0 ); CSingleLock pQueueLock( &UploadQueues.m_pSection ); int nQueue = 1; if ( pQueueLock.Lock() ) { for ( POSITION pos = UploadQueues.GetIterator() ; pos ; nQueue++ ) { CUploadQueue* pQueue = UploadQueues.GetNext( pos ); pPacket->WritePacket( "HG", ( 4 + 7 ) + 2, TRUE ); pPacket->WritePacket( "SS", 7 ); pPacket->WriteShortBE( pQueue->GetQueuedCount() + pQueue->GetTransferCount() ); pPacket->WriteByte( pQueue->GetTransferCount( TRUE ) ); pPacket->WriteLongBE( pQueue->GetPredictedBandwidth() * 8 / 1024 ); pPacket->WriteByte( 0 ); pPacket->WriteByte( nQueue ); } pQueueLock.Unlock(); } CString strNick = MyProfile.GetNick(); if ( strNick.GetLength() > 32 ) strNick = strNick.Left( 32 ); if ( strNick.GetLength() ) { int nNick = pPacket->GetStringLen( strNick ); pPacket->WritePacket( "UPRO", nNick + 6, TRUE ); pPacket->WritePacket( "NICK", nNick ); pPacket->WriteString( strNick, FALSE ); } if ( Settings.Community.ServeProfile ) pPacket->WritePacket( "BUP", 0 ); if ( Settings.Community.ServeFiles ) pPacket->WritePacket( "BH", 0 ); if ( Settings.Community.ChatEnable ) pPacket->WritePacket( "PCH", 0 ); }
void CLocalSearch::AddHit(CDownload* pDownload, int nIndex) { ASSERT( m_pPacket != NULL ); CG2Packet* pPacket = (CG2Packet*)m_pPacket; DWORD nGroup = 2 + 4 + 4; CString strURL; if ( pDownload->m_bTiger && pDownload->m_bSHA1 ) { nGroup += 5 + 3 + sizeof(SHA1) + sizeof(TIGEROOT); } else if ( pDownload->m_bSHA1 ) { nGroup += 5 + 5 + sizeof(SHA1); } else if ( pDownload->m_bTiger ) { nGroup += 5 + 4 + sizeof(TIGEROOT); } if ( pDownload->m_bED2K ) { nGroup += 5 + 5 + sizeof(MD4); } if ( pDownload->m_bBTH ) { nGroup += 5 + 5 + sizeof(SHA1); } if ( m_pSearch->m_bWantDN ) { nGroup += 8 + pPacket->GetStringLen( pDownload->m_sRemoteName ); } if ( m_pSearch->m_bWantURL ) { nGroup += 5; // if ( m_pSearch->m_bBTH && pDownload->m_pTorrent.IsAvailable() && Network.IsListening() ) if ( m_pSearch->m_bBTH && pDownload->m_pTorrent.IsAvailable() && Network.m_pHost.sin_addr.S_un.S_addr != 0 ) { strURL.Format( _T("btc://%s:%i/%s/%s/"), (LPCTSTR)CString( inet_ntoa( Network.m_pHost.sin_addr ) ), htons( Network.m_pHost.sin_port ), (LPCTSTR)CSHA::HashToString( &pDownload->m_pPeerID ),//(LPCTSTR)CSHA::HashToString( BTClients.GetGUID() ), (LPCTSTR)CSHA::HashToString( &pDownload->m_pBTH ) ); nGroup += pPacket->GetStringLen( strURL ); } } pPacket->WritePacket( "H", nGroup, TRUE ); if ( pDownload->m_bTiger && pDownload->m_bSHA1 ) { pPacket->WritePacket( "URN", 3 + sizeof(SHA1) + sizeof(TIGEROOT) ); pPacket->WriteString( "bp" ); pPacket->Write( &pDownload->m_pSHA1, sizeof(SHA1) ); pPacket->Write( &pDownload->m_pTiger, sizeof(TIGEROOT) ); } else if ( pDownload->m_bTiger ) { pPacket->WritePacket( "URN", 4 + sizeof(TIGEROOT) ); pPacket->WriteString( "ttr" ); pPacket->Write( &pDownload->m_pTiger, sizeof(TIGEROOT) ); } else if ( pDownload->m_bSHA1 ) { pPacket->WritePacket( "URN", 5 + sizeof(SHA1) ); pPacket->WriteString( "sha1" ); pPacket->Write( &pDownload->m_pSHA1, sizeof(SHA1) ); } if ( pDownload->m_bED2K ) { pPacket->WritePacket( "URN", 5 + sizeof(MD4) ); pPacket->WriteString( "ed2k" ); pPacket->Write( &pDownload->m_pED2K, sizeof(MD4) ); } if ( pDownload->m_bBTH ) { pPacket->WritePacket( "URN", 5 + sizeof(SHA1) ); pPacket->WriteString( "btih" ); pPacket->Write( &pDownload->m_pBTH, sizeof(SHA1) ); } if ( m_pSearch->m_bWantDN ) { if ( pDownload->m_nSize <= 0xFFFFFFFF ) { pPacket->WritePacket( "DN", pPacket->GetStringLen( pDownload->m_sRemoteName ) + 4 ); pPacket->WriteLongBE( (DWORD)pDownload->m_nSize ); pPacket->WriteString( pDownload->m_sRemoteName, FALSE ); } else { pPacket->WritePacket( "SZ", 8 ); pPacket->WriteInt64( pDownload->m_nSize ); pPacket->WritePacket( "DN", pPacket->GetStringLen( pDownload->m_sRemoteName ) ); pPacket->WriteString( pDownload->m_sRemoteName, FALSE ); } } if ( m_pSearch->m_bWantURL ) { if ( strURL.GetLength() > 0 ) { pPacket->WritePacket( "URL", pPacket->GetStringLen( strURL ) ); pPacket->WriteString( strURL, FALSE ); } else { pPacket->WritePacket( "URL", 0 ); } } QWORD nComplete = pDownload->GetVolumeComplete(); if ( nComplete <= 0xFFFFFFFF ) { pPacket->WritePacket( "PART", 4 ); pPacket->WriteLongBE( (DWORD)nComplete ); } else { pPacket->WritePacket( "PART", 8 ); pPacket->WriteInt64( nComplete ); } }
BOOL CLocalSearch::AddHitG2(CLibraryFile* pFile, int nIndex) { CG2Packet* pPacket = (CG2Packet*)m_pPacket; CString strMetadata, strComment; BOOL bCollection = FALSE; BOOL bPreview = FALSE; DWORD nGroup = 0; // Pass 1: Calculate child group size if ( pFile->m_bTiger && pFile->m_bSHA1 ) { nGroup += 5 + 3 + sizeof(SHA1) + sizeof(TIGEROOT); } else if ( pFile->m_bTiger ) { nGroup += 5 + 4 + sizeof(TIGEROOT); } else if ( pFile->m_bSHA1 ) { nGroup += 5 + 5 + sizeof(SHA1); } if ( pFile->m_bED2K ) { nGroup += 5 + 5 + sizeof(MD4); } if ( m_pSearch == NULL || m_pSearch->m_bWantDN ) { if ( pFile->GetSize() <= 0xFFFFFFFF ) { nGroup += 8 + pPacket->GetStringLen( pFile->m_sName ); } else { nGroup += 4 + 8; nGroup += 4 + pPacket->GetStringLen( pFile->m_sName ); } if ( LPCTSTR pszType = _tcsrchr( pFile->m_sName, '.' ) ) { if ( _tcsicmp( pszType, _T(".co") ) == 0 || _tcsicmp( pszType, _T(".collection") ) == 0 ) { if ( ! pFile->m_bBogus ) { nGroup += 2 + 7; bCollection = TRUE; } } } } if ( pFile->IsAvailable() && ( m_pSearch == NULL || m_pSearch->m_bWantURL ) ) { nGroup += 5; if ( pFile->m_pSources.GetCount() ) nGroup += 7; if ( Settings.Uploads.SharePreviews ) { if ( pFile->m_bCachedPreview || _tcsistr( pFile->m_sName, _T(".jpg") ) || _tcsistr( pFile->m_sName, _T(".png") ) ) { bPreview = TRUE; } } if ( bPreview ) nGroup += 5; } if ( pFile->m_pMetadata != NULL && ( m_pSearch == NULL || m_pSearch->m_bWantXML ) ) { strMetadata = pFile->m_pMetadata->ToString(); int nMetadata = pPacket->GetStringLen( strMetadata ); nGroup += 4 + nMetadata; if ( nMetadata > 0xFF ) { nGroup ++; if ( nMetadata > 0xFFFF ) nGroup ++; } } if ( m_pSearch == NULL || m_pSearch->m_bWantCOM ) { if ( pFile->m_nRating > 0 || pFile->m_sComments.GetLength() > 0 ) { if ( pFile->m_nRating > 0 ) { strComment.Format( _T("<comment rating=\"%i\">"), pFile->m_nRating - 1 ); CXMLNode::ValueToString( pFile->m_sComments, strComment ); if ( strComment.GetLength() > 2048 ) strComment = strComment.Left( 2048 ); strComment += _T("</comment>"); } else { strComment = _T("<comment>"); CXMLNode::ValueToString( pFile->m_sComments, strComment ); if ( strComment.GetLength() > 2048 ) strComment = strComment.Left( 2048 ); strComment += _T("</comment>"); } Replace( strComment, _T("\r\n"), _T("{n}") ); int nComment = pPacket->GetStringLen( strComment ); nGroup += 5 + nComment; if ( nComment > 0xFF ) { nGroup ++; if ( nComment > 0xFFFF ) nGroup ++; } } if ( pFile->m_bBogus ) nGroup += 7; } else { if ( ! pFile->IsAvailable() ) return FALSE; } if ( m_pSearch == NULL ) nGroup += 8; nGroup += 4; // Pass 2: Write the child packet pPacket->WritePacket( "H", nGroup, TRUE ); if ( pFile->m_bTiger && pFile->m_bSHA1 ) { pPacket->WritePacket( "URN", 3 + sizeof(SHA1) + sizeof(TIGEROOT) ); pPacket->WriteString( "bp" ); pPacket->Write( &pFile->m_pSHA1, sizeof(SHA1) ); pPacket->Write( &pFile->m_pTiger, sizeof(TIGEROOT) ); } else if ( pFile->m_bTiger ) { pPacket->WritePacket( "URN", 4 + sizeof(TIGEROOT) ); pPacket->WriteString( "ttr" ); pPacket->Write( &pFile->m_pTiger, sizeof(TIGEROOT) ); } else if ( pFile->m_bSHA1 ) { pPacket->WritePacket( "URN", 5 + sizeof(SHA1) ); pPacket->WriteString( "sha1" ); pPacket->Write( &pFile->m_pSHA1, sizeof(SHA1) ); } if ( pFile->m_bED2K ) { pPacket->WritePacket( "URN", 5 + sizeof(MD4) ); pPacket->WriteString( "ed2k" ); pPacket->Write( &pFile->m_pED2K, sizeof(MD4) ); } if ( m_pSearch == NULL || m_pSearch->m_bWantDN ) { if ( pFile->GetSize() <= 0xFFFFFFFF ) { pPacket->WritePacket( "DN", pPacket->GetStringLen( pFile->m_sName ) + 4 ); pPacket->WriteLongBE( (DWORD)pFile->GetSize() ); pPacket->WriteString( pFile->m_sName, FALSE ); } else { pPacket->WritePacket( "SZ", 8 ); pPacket->WriteInt64( pFile->GetSize() ); pPacket->WritePacket( "DN", pPacket->GetStringLen( pFile->m_sName ) ); pPacket->WriteString( pFile->m_sName, FALSE ); } if ( bCollection ) pPacket->WritePacket( "COLLECT", 0 ); } { CSingleLock pQueueLock( &UploadQueues.m_pSection, TRUE ); CUploadQueue* pQueue = UploadQueues.SelectQueue( PROTOCOL_HTTP, pFile ); pPacket->WritePacket( "G", 1 ); pPacket->WriteByte( pQueue ? pQueue->m_nIndex + 1 : 0 ); } if ( pFile->IsAvailable() && ( m_pSearch == NULL || m_pSearch->m_bWantURL ) ) { pPacket->WritePacket( "URL", 0 ); if ( int nCount = pFile->m_pSources.GetCount() ) { pPacket->WritePacket( "CSC", 2 ); pPacket->WriteShortBE( (WORD)nCount ); } if ( bPreview ) { pPacket->WritePacket( "PVU", 0 ); } } if ( strMetadata.GetLength() ) { pPacket->WritePacket( "MD", pPacket->GetStringLen( strMetadata ) ); pPacket->WriteString( strMetadata, FALSE ); } if ( m_pSearch == NULL || m_pSearch->m_bWantCOM ) { if ( strComment.GetLength() ) { pPacket->WritePacket( "COM", pPacket->GetStringLen( strComment ) ); pPacket->WriteString( strComment, FALSE ); } if ( pFile->m_bBogus ) pPacket->WritePacket( "BOGUS", 0 ); } if ( m_pSearch == NULL ) { pPacket->WritePacket( "ID", 4 ); pPacket->WriteLongBE( pFile->m_nIndex ); } return TRUE; }
CG2Packet* CNeighboursWithG2::CreateQueryWeb(GGUID* pGUID, CNeighbour* pExcept) { CG2Packet* pPacket = CG2Packet::New( G2_PACKET_QUERY_ACK, TRUE ); DWORD tNow = time( NULL ); pPacket->WritePacket( "TS", 4 ); pPacket->WriteLongBE( tNow ); theApp.Message( MSG_DEBUG, _T("Creating a query acknowledgement:") ); pPacket->WritePacket( "D", 8 ); pPacket->WriteLongLE( Network.m_pHost.sin_addr.S_un.S_addr ); pPacket->WriteShortBE( htons( Network.m_pHost.sin_port ) ); pPacket->WriteShortBE( GetCount( PROTOCOL_G2, nrsConnected, ntLeaf ) ); for ( POSITION pos = GetIterator() ; pos ; ) { CG2Neighbour* pNeighbour = (CG2Neighbour*)GetNext( pos ); if ( pNeighbour->m_nProtocol == PROTOCOL_G2 && pNeighbour->m_nNodeType != ntLeaf && pNeighbour->m_nState >= nrsConnected && pNeighbour != pExcept ) { pPacket->WritePacket( "D", 8 ); pPacket->WriteLongLE( pNeighbour->m_pHost.sin_addr.S_un.S_addr ); pPacket->WriteShortBE( htons( pNeighbour->m_pHost.sin_port ) ); pPacket->WriteShortBE( (WORD)pNeighbour->m_nLeafCount ); theApp.Message( MSG_DEBUG, _T(" Done neighbour %s"), (LPCTSTR)pNeighbour->m_sAddress ); } } int nCount = ( pExcept == NULL ) ? 3 : 25; for ( CHostCacheHost* pHost = HostCache.Gnutella2.GetNewest() ; pHost ; pHost = pHost->m_pPrevTime ) { if ( pHost->CanQuote( tNow ) && Get( &pHost->m_pAddress ) == NULL && HubHorizonPool.Find( &pHost->m_pAddress ) == NULL ) { pPacket->WritePacket( "S", 10 ); pPacket->WriteLongLE( pHost->m_pAddress.S_un.S_addr ); pPacket->WriteShortBE( pHost->m_nPort ); pPacket->WriteLongBE( pHost->m_tSeen ); theApp.Message( MSG_DEBUG, _T(" Try cached hub %s"), (LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) ); if ( ! --nCount ) break; } } HubHorizonPool.AddHorizonHubs( pPacket ); pPacket->WriteByte( 0 ); pPacket->Write( pGUID, sizeof(GGUID) ); return pPacket; }
// Takes a GUID, and a neighbour to except from the packet we will make // Makes a Gnutella2 query web packet, containing the IP addresses of the computers we are connected to and from the Gnutella2 host cache CG2Packet* CNeighboursWithG2::CreateQueryWeb(const Hashes::Guid& oGUID, bool bWithHubs, CNeighbour* pExcept, bool bDone) { // Make a new Gnutella2 Query Ack packet CG2Packet* pPacket = CG2Packet::New( G2_PACKET_QUERY_ACK, TRUE ); if ( ! pPacket ) return NULL; // Start it with the text "TS" and the time now const DWORD tNow = static_cast< DWORD >( time( NULL ) ); // Number of seconds since 1970 pPacket->WritePacket( G2_PACKET_TIMESTAMP, 4 ); pPacket->WriteLongBE( tNow ); // Write in header information about us pPacket->WritePacket( G2_PACKET_FROM_ADDRESS, 4 ); pPacket->WriteLongLE( Network.m_pHost.sin_addr.S_un.S_addr ); pPacket->WritePacket( G2_PACKET_RETRY_AFTER, 4 ); pPacket->WriteLongBE( Settings.Gnutella2.QueryThrottle ); if ( bDone ) { pPacket->WritePacket( G2_PACKET_QUERY_DONE, 8 ); pPacket->WriteLongLE( Network.m_pHost.sin_addr.S_un.S_addr ); pPacket->WriteShortBE( htons( Network.m_pHost.sin_port ) ); if ( bWithHubs ) { const WORD nLeafs = (WORD)GetCount( PROTOCOL_G2, nrsConnected, ntLeaf ); pPacket->WriteShortBE( nLeafs ); // Loop through the connected computers for ( POSITION pos = GetIterator() ; pos ; ) { // Get the neighbour object at this position, and move pos to the next one CG2Neighbour* pNeighbour = (CG2Neighbour*)GetNext( pos ); // If this neighbour is running Gnutella2 software if ( pNeighbour->m_nProtocol == PROTOCOL_G2 && // The remote computer is running Gnutella2 software, and pNeighbour->m_nNodeType != ntLeaf && // Our connection to it is not down to a leaf, and pNeighbour->m_nState >= nrsConnected && // We've finished the handshake with it, and pNeighbour != pExcept ) // This isn't the computer the caller warned us to except { // Write information about this connected computer into the packet pPacket->WritePacket( G2_PACKET_QUERY_DONE, 8 ); pPacket->WriteLongLE( pNeighbour->m_pHost.sin_addr.S_un.S_addr ); pPacket->WriteShortBE( htons( pNeighbour->m_pHost.sin_port ) ); pPacket->WriteShortBE( (WORD)pNeighbour->m_nLeafCount ); } } // Will put up to 3 or 25 IP addresses in the packet: // If caller didn't give us a computer to ignore make nCount 3, if it did give us an except make nCount 25 int nCount = ( pExcept == NULL ) ? 3 : 25; CQuickLock oLock( HostCache.Gnutella2.m_pSection ); // Loop, starting with the newest entry in the Gnutella2 host cache, then stepping to the one before that for ( CHostCacheIterator i = HostCache.Gnutella2.Begin() ; i != HostCache.Gnutella2.End() ; ++i ) { CHostCacheHostPtr pHost = (*i); // If this host cache entry is good if ( pHost->CanQuote( tNow ) && // If this host cache entry hasn't expired, and Get( pHost->m_pAddress ) == NULL && // We're connected to that IP address right now, and HubHorizonPool.Find( &pHost->m_pAddress ) == NULL ) // The IP address is also in the hub horizon pool { // Add the IP address to the packet we're making, to encourage recipient to try this address pPacket->WritePacket( G2_PACKET_QUERY_SEARCH, 10 ); pPacket->WriteLongLE( pHost->m_pAddress.S_un.S_addr ); pPacket->WriteShortBE( pHost->m_nPort ); pPacket->WriteLongBE( pHost->Seen() ); // Lower the count, if it is then 0, leave the loop if ( ! --nCount ) break; } } // Give the packet we're making to our own hub horizon pool HubHorizonPool.AddHorizonHubs( pPacket ); } else // No hubs { pPacket->WriteShortBE( 0 ); } } // Finish the packet with a 0 byte and the guid the caller gave us, and return it pPacket->WriteByte( 0 ); pPacket->Write( oGUID ); return pPacket; }
CG2Packet* CLocalSearch::CreatePacketG2() { CG2Packet* pPacket = CG2Packet::New( G2_PACKET_HIT, TRUE ); pPacket->WritePacket( G2_PACKET_NODE_GUID, Hashes::Guid::byteCount ); pPacket->Write( Hashes::Guid( MyProfile.oGUID ) ); pPacket->WritePacket( G2_PACKET_NODE_ADDRESS, 6 ); pPacket->WriteLongLE( Network.m_pHost.sin_addr.s_addr ); pPacket->WriteShortBE( htons( Network.m_pHost.sin_port ) ); pPacket->WritePacket( G2_PACKET_VENDOR, 4 ); pPacket->WriteString( VENDOR_CODE, FALSE ); if ( Network.IsFirewalled() ) { pPacket->WritePacket( G2_PACKET_PEER_FIREWALLED, 0 ); } { CSingleLock pNetLock( &Network.m_pSection ); if ( pNetLock.Lock( 50 ) ) { for ( POSITION pos = Neighbours.GetIterator() ; pos ; ) { CNeighbour* pNeighbour = Neighbours.GetNext( pos ); if ( pNeighbour->m_nNodeType != ntLeaf && pNeighbour->m_nProtocol == PROTOCOL_G2 ) { pPacket->WritePacket( G2_PACKET_NEIGHBOUR_HUB, 6 ); pPacket->WriteLongLE( pNeighbour->m_pHost.sin_addr.s_addr ); pPacket->WriteShortBE( htons( pNeighbour->m_pHost.sin_port ) ); } } } } if ( ! Uploads.m_bStable ) pPacket->WritePacket( G2_PACKET_PEER_UNSTABLE, 0 ); CSingleLock pQueueLock( &UploadQueues.m_pSection ); int nQueue = 1; if ( pQueueLock.Lock() ) { for ( POSITION pos = UploadQueues.GetIterator() ; pos ; nQueue++ ) { CUploadQueue* pQueue = UploadQueues.GetNext( pos ); pPacket->WritePacket( G2_PACKET_HIT_GROUP, ( 4 + 7 ) + 2, TRUE ); pPacket->WritePacket( G2_PACKET_PEER_STATUS, 7 ); pPacket->WriteShortBE( WORD( pQueue->GetQueuedCount() + pQueue->GetTransferCount() ) ); pPacket->WriteByte( BYTE( pQueue->GetTransferCount( TRUE ) ) ); pPacket->WriteLongBE( pQueue->GetPredictedBandwidth() * 8 / 1024 ); pPacket->WriteByte( 0 ); pPacket->WriteByte( BYTE( nQueue ) ); } pQueueLock.Unlock(); } CString strNick = MyProfile.GetNick(); if ( strNick.GetLength() > 32 ) strNick = strNick.Left( 32 ); if ( strNick.GetLength() ) { int nNick = pPacket->GetStringLen( strNick ); pPacket->WritePacket( G2_PACKET_PROFILE, nNick + 6, TRUE ); pPacket->WritePacket( G2_PACKET_NICK, nNick ); pPacket->WriteString( strNick, FALSE ); } if ( Settings.Community.ServeProfile ) pPacket->WritePacket( G2_PACKET_BROWSE_PROFILE, 0 ); if ( Settings.Community.ServeFiles ) pPacket->WritePacket( G2_PACKET_BROWSE_HOST, 0 ); if ( Settings.Community.ChatEnable ) pPacket->WritePacket( G2_PACKET_PEER_CHAT, 0 ); return pPacket; }