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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
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;
}
Beispiel #20
0
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;
}