Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

Uploads.cpp

Go to the documentation of this file.
00001 //
00002 // Uploads.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Uploads.h"
00026 #include "UploadQueue.h"
00027 #include "UploadQueues.h"
00028 #include "UploadTransfer.h"
00029 #include "UploadTransferHTTP.h"
00030 #include "UploadTransferED2K.h"
00031 #include "UploadTransferBT.h"
00032 
00033 #include "Buffer.h"
00034 #include "Transfers.h"
00035 #include "Neighbours.h"
00036 #include "Statistics.h"
00037 #include "Remote.h"
00038 #include "SHA.h"
00039 
00040 #include "WndMain.h"
00041 #include "WndMedia.h"
00042 
00043 #ifdef _DEBUG
00044 #undef THIS_FILE
00045 static char THIS_FILE[]=__FILE__;
00046 #define new DEBUG_NEW
00047 #endif
00048 
00049 CUploads Uploads;
00050 
00051 
00053 // CUploads construction
00054 
00055 CUploads::CUploads()
00056 {
00057         m_nCount                = 0;
00058         m_nBandwidth    = 0;
00059         m_nTorrentSpeed = 0;
00060         m_bStable               = FALSE;
00061         m_nBestSpeed    = 0;
00062 }
00063 
00064 CUploads::~CUploads()
00065 {
00066         Clear( FALSE );
00067 }
00068 
00070 // CUploads clear
00071 
00072 void CUploads::Clear(BOOL bMessage)
00073 {
00074         for ( POSITION pos = GetIterator() ; pos ; )
00075         {
00076                 GetNext( pos )->Remove( bMessage );
00077         }
00078         
00079         ASSERT( GetCount( NULL, -1 ) == 0 );
00080 }
00081 
00083 // CUploads counting
00084 
00085 int CUploads::GetCount(CUploadTransfer* pExcept, int nState) const
00086 {
00087         if ( pExcept == NULL && nState == -1 ) return m_pList.GetCount();
00088         
00089         int nCount = 0;
00090         
00091         for ( POSITION pos = GetIterator() ; pos ; )
00092         {
00093                 CUploadTransfer* pUpload = GetNext( pos );
00094                 
00095                 if ( pUpload != pExcept )
00096                 {
00097                         switch ( nState )
00098                         {
00099                         case -1:
00100                                 nCount++;
00101                                 break;
00102                         case -2:
00103                                 if ( pUpload->m_nState > upsNull ) nCount++;
00104                                 break;
00105                         default:
00106                                 if ( pUpload->m_nState == nState ) nCount++;
00107                                 break;
00108                         }
00109                 }
00110         }
00111         
00112         return nCount;
00113 }
00114 
00115 int CUploads::GetTorrentCount(int nState) const
00116 {
00117         int nCount = 0;
00118         
00119         for ( POSITION pos = GetIterator() ; pos ; )
00120         {
00121                 CUploadTransfer* pUpload = GetNext( pos );
00122 
00123                 if ( pUpload->m_nProtocol == PROTOCOL_BT )
00124                 {
00125                         switch ( nState )
00126                         {
00127                         case -1:
00128                                 nCount++;
00129                                 break;
00130                         case -2:
00131                                 if ( pUpload->m_nState > upsNull ) nCount++;
00132                                 break;
00133                         case -3:
00134                                 if ( pUpload->m_nState >= upsUploading ) nCount++;
00135                                 break;
00136                         default:
00137                                 if ( pUpload->m_nState == nState ) nCount++;
00138                                 break;
00139                         }
00140                 }
00141         }
00142         
00143         return nCount;
00144 }
00145 
00147 // CUploads status
00148 
00149 void CUploads::SetStable(DWORD nSpeed)
00150 {
00151         m_bStable               = TRUE;
00152         m_nBestSpeed    = max( m_nBestSpeed, nSpeed );
00153 }
00154 
00155 DWORD CUploads::GetBandwidth() const
00156 {
00157         DWORD nTotal = 0;
00158         
00159         for ( POSITION pos = GetIterator() ; pos ; )
00160         {
00161                 nTotal += GetNext( pos )->GetMeasuredSpeed();
00162         }
00163         
00164         return nTotal;
00165 }
00166 
00168 // CUploads per-host limiting
00169 
00170 BOOL CUploads::AllowMoreTo(IN_ADDR* pAddress) const
00171 {
00172         int nCount = 0;
00173         
00174         for ( POSITION pos = GetIterator() ; pos ; )
00175         {
00176                 CUploadTransfer* pUpload = GetNext( pos );
00177                 
00178                 if ( pUpload->m_nState == upsUploading ||
00179                          pUpload->m_nState == upsQueued )
00180                 {
00181                         if ( pUpload->m_pHost.sin_addr.S_un.S_addr == pAddress->S_un.S_addr )
00182                                 nCount++;
00183                 }
00184         }
00185         
00186         return ( nCount <= Settings.Uploads.MaxPerHost );
00187 }
00188 
00189 BOOL CUploads::CanUploadFileTo(IN_ADDR* pAddress, const SHA1* pSHA1) const
00190 {
00191         int nCount = 0;
00192         
00193         for ( POSITION pos = GetIterator() ; pos ; )
00194         {
00195                 CUploadTransfer* pUpload = GetNext( pos );
00196                 
00197                 if ( pUpload->m_nState == upsUploading ||
00198                          pUpload->m_nState == upsQueued )
00199                 {
00200                         if ( pUpload->m_pHost.sin_addr.S_un.S_addr == pAddress->S_un.S_addr )
00201                         {
00202                                 nCount++;
00203 
00204                                 // If we're already uploading this file to this client
00205                                 if ( ( pUpload->m_bSHA1 ) && ( pSHA1 ) && ( pUpload->m_pSHA1 == *pSHA1 ) )
00206                                         return FALSE;
00207                         }
00208                 }
00209         }
00210         
00211         return ( nCount < Settings.Uploads.MaxPerHost );
00212 }
00213 
00214 BOOL CUploads::EnforcePerHostLimit(CUploadTransfer* pHit, BOOL bRequest)
00215 {
00216         int nCount = 0;
00217         
00218         for ( POSITION pos = GetIterator() ; pos ; )
00219         {
00220                 CUploadTransfer* pUpload = GetNext( pos );
00221 
00222                 if ( pUpload->m_nState == upsUploading ||
00223                          pUpload->m_nState == upsQueued ||
00224                          pUpload->m_nState == upsPreQueue )
00225                 {
00226                         if ( pUpload->m_pHost.sin_addr.S_un.S_addr == pHit->m_pHost.sin_addr.S_un.S_addr )
00227                                 nCount++;
00228                 }
00229         }
00230         
00231         if ( nCount <= Settings.Uploads.MaxPerHost ) return FALSE;
00232         
00233         while ( nCount > Settings.Uploads.MaxPerHost )
00234         {
00235                 CUploadTransfer* pNewest = NULL;
00236                 
00237                 for ( POSITION pos = GetIterator() ; pos ; )
00238                 {
00239                         CUploadTransfer* pUpload = GetNext( pos );
00240                         
00241                         if ( pUpload->m_nState == upsUploading ||
00242                                  pUpload->m_nState == upsQueued ||
00243                                  pUpload->m_nState == upsPreQueue )
00244                         {
00245                                 if ( pUpload != pHit && pUpload->m_pHost.sin_addr.S_un.S_addr == pHit->m_pHost.sin_addr.S_un.S_addr )
00246                                 {
00247                                         if ( bRequest && pUpload->m_pBaseFile == pHit->m_pBaseFile )
00248                                         {
00249                                                 pNewest = pUpload;
00250                                                 break;
00251                                         }
00252                                         
00253                                         if ( pNewest == NULL || pUpload->m_tConnected > pNewest->m_tConnected )
00254                                                 pNewest = pUpload;
00255                                 }
00256                         }
00257                 }
00258                 
00259                 if ( pNewest == NULL ) break;
00260                 
00261                 if ( bRequest )
00262                 {
00263                         if ( pNewest->m_pBaseFile == pHit->m_pBaseFile && ! pNewest->m_bLive )
00264                         {
00265                                 UploadQueues.StealPosition( pHit, pNewest );
00266                                 
00267                                 theApp.Message( MSG_ERROR, IDS_UPLOAD_DROPPED_OLDER,
00268                                         (LPCTSTR)pNewest->m_sAddress );
00269                                 
00270                                 pNewest->Close( FALSE );
00271                         }
00272                         else
00273                         {
00274                                 return FALSE;
00275                         }
00276                 }
00277                 else
00278                 {
00279                         theApp.Message( MSG_ERROR, IDS_UPLOAD_DROPPED_NEWER, (LPCTSTR)pNewest->m_sAddress );
00280                         pNewest->Close( FALSE );
00281                 }
00282                 
00283                 nCount--;
00284         }
00285         
00286         return FALSE;
00287 }
00288 
00290 // CUploads run
00291 
00292 void CUploads::OnRun()
00293 {
00294         CSingleLock pLock( &UploadQueues.m_pSection, TRUE );
00295         int nCountTorrent = 0;
00296         POSITION pos;
00297         
00298         m_nCount                = 0;
00299         m_nBandwidth    = 0;
00300         
00301         //Set measured queue speeds to 0
00302         for ( pos = UploadQueues.GetIterator() ; pos ; )
00303         {
00304                 UploadQueues.GetNext( pos )->m_nMeasured = 0;
00305         }
00306         UploadQueues.m_pTorrentQueue->m_nMeasured = 0;
00307         UploadQueues.m_pTorrentQueue->m_nMinTransfers = 0;
00308         UploadQueues.m_pTorrentQueue->m_nMaxTransfers = 0;
00309         
00310         for ( pos = GetIterator() ; pos ; )
00311         {
00312                 CUploadTransfer* pTransfer = GetNext( pos );
00313                 DWORD nMeasured = pTransfer->GetMeasuredSpeed();
00314 
00315                 if ( ( pTransfer->m_nProtocol == PROTOCOL_BT ) && ( pTransfer->m_nState != upsNull ) )  
00316                 {
00317                         // This is a torrent transfer
00318                         CUploadTransferBT* pBT = (CUploadTransferBT*)pTransfer;
00319                         if ( ( ! pBT->m_bInterested ) || ( pBT->m_bChoked ) )
00320                         {
00321                                 // Choked- Increment appropriate torrent counter
00322                                 UploadQueues.m_pTorrentQueue->m_nMaxTransfers ++;
00323                         }
00324                         else
00325                         {
00326                                 // Active torrent. (Uploading or requesting)
00327                                 // Increment normal counters
00328                                 m_nCount ++;
00329                                 m_nBandwidth += nMeasured;
00330                                 // Increment torrent counters
00331                                 nCountTorrent ++;
00332                                 UploadQueues.m_pTorrentQueue->m_nMinTransfers ++;
00333                                 UploadQueues.m_pTorrentQueue->m_nMeasured += nMeasured;
00334 
00335                                 //theApp.Message( MSG_SYSTEM, pTransfer->m_sAddress );
00336                                 //theApp.Message( MSG_SYSTEM, _T("Port: %i "), pTransfer->m_pHost.sin_port );
00337                         }
00338                 }
00339                 else if ( pTransfer->m_nState == upsUploading )
00340                 {
00341                         // Regular transfer that's uploading
00342                         m_nCount ++;
00343                         m_nBandwidth += nMeasured;
00344 
00345                         if ( pTransfer->m_pQueue != NULL && UploadQueues.Check( pTransfer->m_pQueue ) )
00346                                 pTransfer->m_pQueue->m_nMeasured += nMeasured;
00347                 }
00348         }
00349         
00350         if ( nCountTorrent > 0 )        //If there are any active torrents
00351         {       //Assign bandwidth to BT (4/5ths by default)
00352                 m_nTorrentSpeed = Settings.Bandwidth.Uploads;
00353                 if ( m_nTorrentSpeed == 0 ) m_nTorrentSpeed = 0xFFFFFFFF;
00354                 m_nTorrentSpeed = min( m_nTorrentSpeed, Settings.Connection.OutSpeed * 128 );
00355                 m_nTorrentSpeed = m_nTorrentSpeed * Settings.BitTorrent.BandwidthPercentage / 100;
00356                 
00357                 m_nTorrentSpeed = m_nTorrentSpeed / nCountTorrent;
00358                 m_nTorrentSpeed = max( m_nTorrentSpeed, Settings.Bandwidth.Request );
00359         }
00360         else
00361         {       //If there are no torrents, set to zero
00362                 m_nTorrentSpeed = 0;
00363         }
00364 }
00365 
00367 // CUploads get connection
00368 
00369 BOOL CUploads::OnAccept(CConnection* pConnection, LPCTSTR pszHandshake)
00370 {
00371         CSingleLock pLock( &Transfers.m_pSection );
00372         if ( ! pLock.Lock( 250 ) ) return FALSE;
00373         
00374         if ( Settings.Remote.Enable && ( _tcsncmp( pszHandshake, _T("GET /remote/"), 12 ) == 0 ) )
00375         {
00376                 new CRemote( pConnection );
00377                 return TRUE;
00378         }
00379         else if ( Settings.Remote.Enable && ( _tcsncmp( pszHandshake, _T("GET /remote HTTP"), 16 ) == 0 ) )
00380         {
00381                 // The user entered the remote page into a browser, but forgot the trailing '/'
00382                 new CRemote( pConnection );
00383                 return TRUE;
00384         }
00385         else if ( Settings.Uploads.MaxPerHost > 0 )
00386         {
00387                 CUploadTransfer* pUpload = new CUploadTransferHTTP();
00388                 
00389                 for ( POSITION pos = GetIterator() ; pos ; )
00390                 {
00391                         CUploadTransfer* pTest = GetNext( pos );
00392                         
00393                         if (    pTest->m_pHost.sin_addr.S_un.S_addr ==
00394                                         pConnection->m_pHost.sin_addr.S_un.S_addr )
00395                         {
00396                                 pTest->m_bLive = FALSE;
00397                         }
00398                 }
00399                 
00400                 pUpload->AttachTo( pConnection );
00401                 
00402                 return TRUE;
00403         }
00404         
00405         return FALSE;
00406 }
00407 
00409 // CUploads rename handler
00410 
00411 void CUploads::OnRename(LPCTSTR pszSource, LPCTSTR pszTarget)
00412 {
00413         CSingleLock pLock( &Transfers.m_pSection );
00414         
00415         if ( pLock.Lock( 500 ) )
00416         {
00417                 for ( POSITION pos = GetIterator() ; pos ; )
00418                 {
00419                         GetNext( pos )->OnRename( pszSource, pszTarget );
00420                 }
00421                 
00422                 pLock.Unlock();
00423         }
00424         
00425         CSingleLock pLock2( &theApp.m_pSection );
00426         
00427         if ( pLock2.Lock( 500 ) )
00428         {
00429                 if ( CMainWnd* pMainWnd = (CMainWnd*)theApp.m_pSafeWnd )
00430                 {
00431                         CMediaWnd* pMediaWnd = (CMediaWnd*)pMainWnd->m_pWindows.Find(
00432                                 RUNTIME_CLASS(CMediaWnd) );
00433                         
00434                         if ( pMediaWnd != NULL )
00435                         {
00436                                 pMediaWnd->OnFileDelete( pszSource );
00437                         }
00438                 }
00439                 
00440                 pLock2.Unlock();
00441         }
00442 }
00443 
00445 // CUploads add and remove
00446 
00447 void CUploads::Add(CUploadTransfer* pUpload)
00448 {
00449         POSITION pos = m_pList.Find( pUpload );
00450         ASSERT( pos == NULL );
00451         m_pList.AddHead( pUpload );
00452 }
00453 
00454 void CUploads::Remove(CUploadTransfer* pUpload)
00455 {
00456         POSITION pos = m_pList.Find( pUpload );
00457         ASSERT( pos != NULL );
00458         m_pList.RemoveAt( pos );
00459 }
00460 

Generated on Thu Dec 15 10:39:50 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2