00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
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
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
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
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
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
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
00318 CUploadTransferBT* pBT = (CUploadTransferBT*)pTransfer;
00319 if ( ( ! pBT->m_bInterested ) || ( pBT->m_bChoked ) )
00320 {
00321
00322 UploadQueues.m_pTorrentQueue->m_nMaxTransfers ++;
00323 }
00324 else
00325 {
00326
00327
00328 m_nCount ++;
00329 m_nBandwidth += nMeasured;
00330
00331 nCountTorrent ++;
00332 UploadQueues.m_pTorrentQueue->m_nMinTransfers ++;
00333 UploadQueues.m_pTorrentQueue->m_nMeasured += nMeasured;
00334
00335
00336
00337 }
00338 }
00339 else if ( pTransfer->m_nState == upsUploading )
00340 {
00341
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 )
00351 {
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 {
00362 m_nTorrentSpeed = 0;
00363 }
00364 }
00365
00367
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
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
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
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