// Find the newest neighbor object CNeighbour* CNeighboursBase::GetNewest(PROTOCOLID nProtocol, int nState, int nNodeType) const { ASSUME_LOCK( Network.m_pSection ); const DWORD tNow = GetTickCount(); DWORD tMinTime = 0xffffffff; CNeighbour* pNewestNeighbour = NULL; for ( POSITION pos = GetIterator() ; pos ; ) { CNeighbour* pNeighbour = GetNext( pos ); if ( ( nProtocol == PROTOCOL_ANY || nProtocol == pNeighbour->m_nProtocol ) && ( nState < 0 || nState == pNeighbour->m_nState ) && ( nNodeType < 0 || nNodeType == pNeighbour->m_nNodeType ) ) { DWORD tTime = tNow - pNeighbour->m_tConnected; if ( tTime < tMinTime ) { tMinTime = tTime; pNewestNeighbour = pNeighbour; } } } return pNewestNeighbour; }
void CDownloadTransfer::Close(TRISTATE bKeepSource, DWORD nRetryAfter) { ASSUME_LOCK( Transfers.m_pSection ); SetState( dtsNull ); // if ( m_nProtocol != PROTOCOL_BT && m_nProtocol != PROTOCOL_ED2K ) CTransfer::Close(); if ( CDownloadSource* pSource = m_pSource ) { m_pSource = NULL; switch ( bKeepSource ) { case TRI_TRUE: if ( pSource->m_bCloseConn && pSource->m_nGnutella ) pSource->OnResumeClosed(); else pSource->OnFailure( TRUE, nRetryAfter ); break; case TRI_UNKNOWN: pSource->OnFailure( FALSE ); break; case TRI_FALSE: pSource->Remove( FALSE, TRUE ); break; } } if ( m_pDownload ) m_pDownload->RemoveTransfer( this ); }
INT_PTR CDownloadSheet::DoModal() { ASSUME_LOCK( Transfers.m_pSection ); CTorrentFilesPage pFiles; CTorrentTrackersPage pTrackers; CTorrentGeneralPage pGeneral; CDownloadEditPage pDownload; CDownloadActionsPage pActions; if ( m_pDownload->IsTorrent() ) { SetTabTitle( &pFiles, m_sFilesTitle ); AddPage( &pFiles ); SetTabTitle( &pTrackers, m_sTrackersTitle ); AddPage( &pTrackers ); SetTabTitle( &pGeneral, m_sGeneralTitle ); AddPage( &pGeneral ); } if ( ! m_pDownload->IsMoving() && ! m_pDownload->IsCompleted() ) { SetTabTitle( &pDownload, m_sDownloadTitle ); AddPage( &pDownload ); SetTabTitle( &pActions, m_sActionsTitle ); AddPage( &pActions ); } return CPropertySheetAdv::DoModal(); }
void CDatagrams::remove(DatagramOut* pDatagramOut) { ASSUME_LOCK(m_pSection); m_SendCacheMap.remove(pDatagramOut->m_nSequence); QLinkedList<DatagramOut*>::iterator itFrame = m_SendCache.end(); while( itFrame != m_SendCache.begin() ) { --itFrame; if( *itFrame == pDatagramOut ) { m_SendCache.erase(itFrame); break; } } m_FreeDatagramOut.append(pDatagramOut); if(pDatagramOut->m_pBuffer) { m_FreeBuffer.append(pDatagramOut->m_pBuffer); pDatagramOut->m_pBuffer->clear(); pDatagramOut->m_pBuffer = 0; } }
bool CDownloadTransferBT::UnrequestRange(QWORD nOffset, QWORD nLength) { ASSUME_LOCK( Transfers.m_pSection ); if ( m_oRequested.empty() ) return false; ASSERT( m_pDownload->m_pTorrent.m_nBlockSize != 0 ); if ( m_pDownload->m_pTorrent.m_nBlockSize == 0 ) return false; Fragments::Queue oUnrequests = extract_range( m_oRequested, Fragments::Fragment( nOffset, nOffset + nLength ) ); for ( Fragments::Queue::const_iterator pFragment = oUnrequests.begin(); pFragment != oUnrequests.end(); ++pFragment ) { m_pClient->Cancel( (DWORD)( pFragment->begin() / m_pDownload->m_pTorrent.m_nBlockSize ), (DWORD)( pFragment->begin() % m_pDownload->m_pTorrent.m_nBlockSize ), (DWORD)( pFragment->size() ) ); } return !oUnrequests.empty(); }
BOOL CDownloadTransferBT::Initiate() { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_pClient == NULL ); ASSERT( m_nState == dtsNull ); theApp.Message( MSG_DEBUG, _T("Connecting to BitTorrent host %s..."), (LPCTSTR)CString( inet_ntoa( m_pSource->m_pAddress ) ) ); m_pClient = new CBTClient(); if ( ! m_pClient->Connect( this ) ) { delete m_pClient; m_pClient = NULL; Close( TRI_FALSE ); return FALSE; } SetState( dtsConnecting ); m_tConnected = GetTickCount(); m_pHost = m_pClient->m_pHost; m_sAddress = m_pClient->m_sAddress; UpdateCountry(); return TRUE; }
CTransfer::CTransfer(void* pOwner, QObject *parent) : CNetworkConnection(parent), m_pOwner(pOwner) { ASSUME_LOCK(Transfers.m_pSection); Transfers.add(this); }
BOOL CDownloadTransferBT::OnChoked(CBTPacket* /*pPacket*/) { ASSUME_LOCK( Transfers.m_pSection ); if ( m_bChoked ) return TRUE; m_bChoked = TRUE; SetState( dtsTorrent ); theApp.Message( MSG_DEBUG, _T("Download from %s was choked."), (LPCTSTR)m_sAddress ); /*for ( Fragments::Queue::const_iterator pFragment = m_oRequested.begin(); pFragment != m_oRequested.end() ; ++pFragment ) { m_pClient->Cancel( (DWORD)( pFragment->begin() / m_pDownload->m_pTorrent.m_nBlockSize ), (DWORD)( pFragment->begin() % m_pDownload->m_pTorrent.m_nBlockSize ), (DWORD)( pFragment->size() ) ); }*/ m_oRequested.clear(); return TRUE; }
CFileList* CLibraryMaps::WhatsNew(const CQuerySearch* pSearch, int nMaximum) const { ASSUME_LOCK( Library.m_pSection ); const DWORD tNow = static_cast< DWORD >( time( NULL ) ); CFileList* pHits = NULL; for ( POSITION pos = GetFileIterator() ; pos ; ) { CLibraryFile* pFile = GetNextFile( pos ); if ( pFile->IsAvailable() && pFile->IsShared() && pFile->m_oSHA1 && ( ! pSearch->m_pSchema || pSearch->m_pSchema->Equals( pFile->m_pSchema ) ) ) { const DWORD nTime = pFile->GetCreationTime(); if ( nTime && nTime + 12 * 60 * 60 > tNow ) // 12 hours { pFile->m_nHitsToday++; pFile->m_nHitsTotal++; if ( ! pHits ) pHits = new CFileList; pHits->AddTail( pFile ); if ( nMaximum && pHits->GetCount() >= nMaximum ) break; } } } return pHits; }
bool CLibraryTileItem::Update() { ASSUME_LOCK( Library.m_pSection ); if ( m_pAlbum->m_nUpdateCookie == m_nCookie ) return false; m_nCookie = m_pAlbum->m_nUpdateCookie; m_sTitle = m_pAlbum->m_sName; m_nIcon32 = m_pAlbum->m_pSchema ? m_pAlbum->m_pSchema->m_nIcon32 : -1; m_nIcon48 = m_pAlbum->m_pSchema ? m_pAlbum->m_pSchema->m_nIcon48 : -1; m_bCollection = m_pAlbum->m_oCollSHA1.isValid(); CSchemaPtr pSchema = m_pAlbum->m_pSchema; if ( pSchema != NULL && m_pAlbum->m_pXML != NULL ) { m_sSubtitle1 = pSchema->m_sTileLine1; m_sSubtitle2 = pSchema->m_sTileLine2; pSchema->ResolveTokens( m_sSubtitle1, m_pAlbum->m_pXML ); pSchema->ResolveTokens( m_sSubtitle2, m_pAlbum->m_pXML ); } else { m_sSubtitle1.Empty(); m_sSubtitle2.Empty(); } return true; }
BOOL CDownloadTransferBT::OnConnected() { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_pClient != NULL ); ASSERT( m_pSource != NULL ); SetState( dtsTorrent ); m_pHost = m_pClient->m_pHost; m_sAddress = m_pClient->m_sAddress; UpdateCountry(); // not deleting source for source exchange. if ( m_pDownload->IsCompleted() ) { // This source is only here to push start torrent uploads. (We don't want to download) m_bInterested = FALSE; theApp.Message( MSG_INFO, _T("Initiated push start for upload to %s"), (LPCTSTR)m_sAddress ); } else { // Regular download m_pClient->m_mInput.pLimit = &m_nBandwidth; theApp.Message( MSG_INFO, IDS_DOWNLOAD_CONNECTED, (LPCTSTR)m_sAddress ); if ( ! m_pDownload->PrepareFile() ) { Close( TRI_TRUE ); return FALSE; } m_pClient->m_mInput.pLimit = &m_nBandwidth; } m_pSource->SetLastSeen(); return TRUE; }
CLibraryTileView::iterator CLibraryTileView::HitTest(const CPoint& point) { ASSUME_LOCK( Library.m_pSection ); CRect rcClient; GetClientRect( &rcClient ); CPoint pt( rcClient.left, rcClient.top - m_nScroll ); for ( iterator pTile = begin(); pTile != end() && pt.y < rcClient.bottom; ++pTile ) { CRect rcBlock( pt.x, pt.y, pt.x + m_szBlock.cx, pt.y + m_szBlock.cy ); if ( rcBlock.PtInRect( point ) ) return pTile; pt.x += m_szBlock.cx; if ( pt.x + m_szBlock.cx > rcClient.right ) { pt.x = rcClient.left; pt.y += m_szBlock.cy; } } return end(); }
void CDownloadWithSources::InternalAdd(CDownloadSource* pSource) { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_pSources.Find( pSource ) == NULL ); m_pSources.AddTail( pSource ); switch ( pSource->m_nProtocol ) { case PROTOCOL_G1: m_nG1SourceCount++; break; case PROTOCOL_G2: m_nG2SourceCount++; break; case PROTOCOL_ED2K: m_nEdSourceCount++; break; case PROTOCOL_BT: m_nBTSourceCount++; break; case PROTOCOL_HTTP: m_nHTTPSourceCount++; break; case PROTOCOL_FTP: m_nFTPSourceCount++; break; case PROTOCOL_DC: m_nDCSourceCount++; break; default: ASSERT( FALSE ); } }
void CDownloadWithSources::InternalRemove(CDownloadSource* pSource) { ASSUME_LOCK( Transfers.m_pSection ); POSITION posSource = m_pSources.Find( pSource ); ASSERT( posSource != NULL ); m_pSources.RemoveAt( posSource ); switch ( pSource->m_nProtocol ) { case PROTOCOL_G1: m_nG1SourceCount--; break; case PROTOCOL_G2: m_nG2SourceCount--; break; case PROTOCOL_ED2K: m_nEdSourceCount--; break; case PROTOCOL_DC: m_nDCSourceCount--; break; case PROTOCOL_BT: m_nBTSourceCount--; break; case PROTOCOL_HTTP: m_nHTTPSourceCount--; break; case PROTOCOL_FTP: m_nFTPSourceCount--; break; //default: // ASSERT( FALSE ); } }
BOOL CHostBrowser::StreamPacketsG2() { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_nProtocol == PROTOCOL_G2 ); while ( CG2Packet* 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; }
BOOL CDownloadTransferBT::OnPiece(CBTPacket* pPacket) { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_pClient != NULL ); if ( pPacket->GetRemaining() < 8 ) return TRUE; if ( m_nState != dtsRequesting && m_nState != dtsDownloading ) return TRUE; SetState( dtsDownloading ); DWORD nBlock = pPacket->ReadLongBE(); QWORD nOffset = pPacket->ReadLongBE(); QWORD nLength = pPacket->GetRemaining(); nOffset += (QWORD)nBlock * m_pDownload->m_pTorrent.m_nBlockSize; m_nDownloaded += nLength; m_pDownload->m_nTorrentDownloaded += nLength; m_pDownload->m_pTorrent.m_nTotalDownload += nLength; m_pSource->AddFragment( nOffset, nLength ); m_pSource->SetValid(); m_oRequested.erase( Fragments::Fragment( nOffset, nOffset + nLength ) ); BOOL bSuccess = m_pDownload->SubmitData( nOffset, pPacket->m_pBuffer + pPacket->m_nPosition, nLength ); if ( ! bSuccess ) TRACE( _T("[BT] Failed to submit data %I64u-%I64u to \"%s\".\n"), nOffset, nOffset + nLength, m_pDownload->m_sPath ); // TODO: SendRequests and ShowInterest could be combined.. SendRequests // is probably going to tell us if we are interested or not ShowInterest(); return SendFragmentRequests(); }
const CQueryHashTable* CLibraryDictionary::GetHashTable() { ASSUME_LOCK( Library.m_pSection ); BuildHashTable(); return m_pTable; }
CDownloadTransferBT::~CDownloadTransferBT() { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_pClient == NULL ); // This never happens if ( m_pClient ) m_pClient->m_mInput.pLimit = m_pClient->m_mOutput.pLimit = NULL; }
void CNeighboursConnections::RemoveNode(CNeighbour* pNode) { ASSUME_LOCK(m_pSection); m_pController->RemoveSocket(pNode); CNeighboursRouting::RemoveNode(pNode); }
BOOL CManagedSearch::Execute(int nPriorityClass) { ASSUME_LOCK( SearchManager.m_pSection ); if ( m_nPriority != nPriorityClass || ! m_bActive || ! m_pSearch ) return FALSE; // Throttle this individual search (so it doesn't take up too many resources) DWORD nThrottle = Settings.Search.GeneralThrottle; if ( m_nPriority == spLowest ) nThrottle += 30000; // + 30s else if ( m_nPriority == spMedium ) nThrottle += 800; // + .8s const DWORD tTicks = GetTickCount(); const DWORD tSecs = static_cast< DWORD >( time( NULL ) ); if ( tTicks < m_tExecute + nThrottle ) return FALSE; m_tExecute = tTicks; // Search local neighbours: hubs, servers and ultrapeers. (TCP) BOOL bSuccess = ExecuteNeighbours( tTicks, tSecs ); // G1 multicast search. (UDP) if ( Settings.Gnutella1.Enabled && m_bAllowG1 && tTicks >= m_tLastG1 + Settings.Gnutella1.QueryGlobalThrottle && Network.IsListening() ) { bSuccess |= ExecuteG1Mesh( tTicks, tSecs ); m_tLastG1 = tTicks; } // G2 global search. (UDP) if ( Settings.Gnutella2.Enabled && m_bAllowG2 && tTicks >= m_tLastG2 + Settings.Gnutella2.QueryGlobalThrottle && Network.IsListening() ) { bSuccess |= ExecuteG2Mesh( tTicks, tSecs ); m_tLastG2 = tTicks; } // ED2K global search. (UDP) if ( Settings.eDonkey.Enabled && Settings.eDonkey.ServerWalk && m_bAllowED2K && tTicks >= m_tLastED2K + Settings.eDonkey.QueryGlobalThrottle && Network.IsListening() && ( m_pSearch->m_oED2K || IsLastSearch() ) ) { bSuccess |= ExecuteDonkeyMesh( tTicks, tSecs ); m_tLastED2K = tTicks; } if ( bSuccess ) m_nQueryCount++; return bSuccess; }
// Calls Close on all the neighbours in the list, and resets member variables back to 0 void CNeighboursBase::Close() { ASSUME_LOCK( Network.m_pSection ); for ( POSITION pos = GetIterator() ; pos ; ) { GetNext( pos )->Close(); } }
CNeighbour* CNeighboursBase::GetNext(POSITION& pos) const { ASSUME_LOCK( Network.m_pSection ); IN_ADDR nAddress; CNeighbour* pNeighbour; m_pNeighbours.GetNextAssoc( pos, nAddress, pNeighbour ); return pNeighbour; }
BOOL CUploadTransferDC::OnWrite() { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_pClient ); m_mOutput.tLast = m_pClient->m_mOutput.tLast; if ( m_pClient->GetOutputLength() != 0 ) // There is data in output buffer return TRUE; if ( m_nState == upsUploading ) { ASSERT( m_nLength != SIZE_UNKNOWN ); // No file data left to transfer if ( m_nPosition >= m_nLength ) { // File completed Uploads.SetStable( GetAverageSpeed() ); m_nState = upsRequest; m_tRequest = GetTickCount(); m_pBaseFile->AddFragment( m_nOffset, m_nLength ); theApp.Message( MSG_INFO, IDS_UPLOAD_FINISHED, (LPCTSTR)m_sName, (LPCTSTR)m_sAddress ); } else { // Reading next data chunk of file QWORD nToRead = min( m_nLength - m_nPosition, (QWORD)Settings.Uploads.ChunkSize ); // ~1000 KB QWORD nRead = 0; auto_array< BYTE > pBuffer( new BYTE[ nToRead ] ); if ( ! ReadFile( m_nFileBase + m_nOffset + m_nPosition, pBuffer.get(), nToRead, &nRead ) || nToRead != nRead ) { // File error return FALSE; } m_pClient->Write( pBuffer.get(), (DWORD)nRead ); m_nPosition += nRead; m_nUploaded += nRead; Statistics.Current.Uploads.Volume += ( nRead / 1024 ); } } else if ( m_nState >= upsResponse ) { // Current transfer completed m_nState = ( m_nState == upsPreQueue ) ? upsQueued : upsRequest; m_tRequest = GetTickCount(); } return TRUE; }
POSITION CUploadsCtrl::GetFileIterator(CUploadQueue* pQueue) { ASSUME_LOCK( Transfers.m_pSection ); if ( pQueue == UploadQueues.m_pTorrentQueue ) { for ( POSITION posNext = UploadFiles.GetIterator() ; posNext ; ) { POSITION posThis = posNext; CUploadFile* pFile = UploadFiles.GetNext( posNext ); CUploadTransfer* pTransfer = pFile->GetActive(); if ( pTransfer == NULL || pTransfer->m_nState == upsNull ) continue; if ( pTransfer->m_nProtocol != PROTOCOL_BT ) continue; return posThis; } return NULL; } else if ( pQueue == UploadQueues.m_pHistoryQueue ) { for ( POSITION posNext = UploadFiles.GetIterator() ; posNext ; ) { POSITION posThis = posNext; CUploadFile* pFile = UploadFiles.GetNext( posNext ); CUploadTransfer* pTransfer = pFile->GetActive(); if ( pTransfer != NULL ) { if ( pTransfer->m_nProtocol == PROTOCOL_BT && pTransfer->m_nState != upsNull ) continue; if ( pTransfer->m_pQueue != NULL ) continue; } return posThis; } return NULL; } else { if ( Settings.Uploads.FilterMask & ULF_ACTIVE ) { if ( pQueue->GetActiveCount() > 0 ) { return pQueue->GetActiveIterator(); } } if ( Settings.Uploads.FilterMask & ULF_QUEUED ) { if ( pQueue->GetQueuedCount() > 0 ) { return (POSITION)1; } } return NULL; } }
BOOL CManagedSearch::ExecuteG1Mesh(const DWORD /*tTicks*/, const DWORD /*tSecs*/) { ASSUME_LOCK( SearchManager.m_pSection ); theApp.Message( MSG_DEBUG | MSG_FACILITY_SEARCH, _T("Multicast querying Gnutella neighbours") ); // protocolNames[ PROTOCOL_G1 ] Neighbours.SendQuery( m_pSearch ); return TRUE; }
BOOL CDownloadTransferBT::SubtractRequested(Fragments::List& ppFragments) const { ASSUME_LOCK( Transfers.m_pSection ); if ( m_oRequested.empty() || m_bChoked ) return FALSE; ppFragments.erase( m_oRequested.begin(), m_oRequested.end() ); return TRUE; }
// Takes a key value as a DWORD (do) // Finds the CNeighbour object that was entered into m_pUniques with that value CNeighbour* CNeighboursBase::Get(DWORD_PTR nUnique) const { ASSUME_LOCK( Network.m_pSection ); CNeighbour* pNeighbour; if ( m_pIndex.Lookup( nUnique, pNeighbour ) ) return pNeighbour; return NULL; }
// Takes an IP address, and finds the neighbour object in the m_pUniques map that represents the remote computer with that address CNeighbour* CNeighboursBase::Get(const IN_ADDR& pAddress) const { ASSUME_LOCK( Network.m_pSection ); CNeighbour* pNeighbour; if ( m_pNeighbours.Lookup( pAddress, pNeighbour ) ) return pNeighbour; return NULL; }
// Takes a neighbour object, and true to find it an unused m_nUnique number // Adds it to the m_pUniques map using pNeighbour->m_nUnique as the key void CNeighboursBase::Add(CNeighbour* pNeighbour) { ASSUME_LOCK( Network.m_pSection ); ASSERT( pNeighbour->m_pHost.sin_addr.s_addr != INADDR_ANY ); ASSERT( pNeighbour->m_pHost.sin_addr.s_addr != INADDR_NONE ); ASSERT( Get( pNeighbour->m_pHost.sin_addr ) == NULL ); ASSERT( Get( (DWORD_PTR)pNeighbour ) == NULL ); m_pNeighbours.SetAt( pNeighbour->m_pHost.sin_addr, pNeighbour ); m_pIndex.SetAt( (DWORD_PTR)pNeighbour, pNeighbour ); }
CDownloadSheet::CDownloadSheet(CSingleLock& pLock, CDownload* pDownload) : m_pLock ( pLock ) , m_pDownload ( pDownload ) , m_sFilesTitle ( L"Files" ) , m_sTrackersTitle ( L"Trackers" ) , m_sGeneralTitle ( L"Torrent" ) , m_sDownloadTitle ( L"General" ) , m_sActionsTitle ( L"Actions" ) { ASSUME_LOCK( Transfers.m_pSection ); }