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 "Download.h"
00026 #include "Downloads.h"
00027 #include "Transfers.h"
00028 #include "DownloadWithTransfers.h"
00029 #include "DownloadSource.h"
00030 #include "DownloadTransferHTTP.h"
00031
00032 #include "DownloadTransferED2K.h"
00033 #include "DownloadTransferBT.h"
00034 #include "Network.h"
00035 #include "EDClient.h"
00036
00037 #ifdef _DEBUG
00038 #undef THIS_FILE
00039 static char THIS_FILE[]=__FILE__;
00040 #define new DEBUG_NEW
00041 #endif
00042
00043
00045
00046
00047 CDownloadWithTransfers::CDownloadWithTransfers()
00048 {
00049 m_pTransferFirst = NULL;
00050 m_pTransferLast = NULL;
00051 m_nTransferCount = 0;
00052 m_tTransferStart = 0;
00053 }
00054
00055 CDownloadWithTransfers::~CDownloadWithTransfers()
00056 {
00057 CloseTransfers();
00058 }
00059
00061
00062
00063 int CDownloadWithTransfers::GetTransferCount() const
00064 {
00065 int nCount = 0;
00066
00067 for ( CDownloadTransfer* pTransfer = m_pTransferFirst; pTransfer; pTransfer = pTransfer->m_pDlNext )
00068 {
00069 if ( ( pTransfer->m_nProtocol != PROTOCOL_ED2K ) ||
00070 ( static_cast< CDownloadTransferED2K* >( pTransfer )->m_pClient &&
00071 static_cast< CDownloadTransferED2K* >( pTransfer )->m_pClient->m_bConnected ) )
00072 {
00073
00074 ++nCount;
00075 }
00076 }
00077 return nCount;
00078 }
00079
00080
00081
00082
00083 #define VALID_TRANSFER ( ! pAddress || pAddress->S_un.S_addr == pTransfer->m_pHost.sin_addr.S_un.S_addr ) && \
00084 ( ( pTransfer->m_nProtocol != PROTOCOL_ED2K ) || \
00085 ( static_cast< CDownloadTransferED2K* >( pTransfer )->m_pClient && \
00086 static_cast< CDownloadTransferED2K* >( pTransfer )->m_pClient->m_bConnected ) )
00087
00088
00089 int CDownloadWithTransfers::GetTransferCount(int nState, IN_ADDR* pAddress) const
00090 {
00091 int nCount = 0;
00092
00093 switch ( nState )
00094 {
00095 case dtsCountAll:
00096 for ( CDownloadTransfer* pTransfer = m_pTransferFirst; pTransfer; pTransfer = pTransfer->m_pDlNext )
00097 {
00098 if ( VALID_TRANSFER )
00099 {
00100 ++nCount;
00101 }
00102 }
00103 return nCount;
00104 case dtsCountNotQueued:
00105 for ( CDownloadTransfer* pTransfer = m_pTransferFirst ; pTransfer ; pTransfer = pTransfer->m_pDlNext )
00106 {
00107 if ( VALID_TRANSFER && ( ( pTransfer->m_nState != dtsQueued ) &&
00108 ( ! ( pTransfer->m_nState == dtsTorrent && static_cast< CDownloadTransferBT* >(pTransfer)->m_bChoked ) ) ) )
00109
00110 {
00111 ++nCount;
00112 }
00113 }
00114 return nCount;
00115 case dtsCountNotConnecting:
00116 for ( CDownloadTransfer* pTransfer = m_pTransferFirst ; pTransfer ; pTransfer = pTransfer->m_pDlNext )
00117 {
00118 if ( ( ! pAddress || pAddress->S_un.S_addr == pTransfer->m_pHost.sin_addr.S_un.S_addr ) &&
00119 ( pTransfer->m_nState > dtsConnecting ) )
00120 {
00121 ++nCount;
00122 }
00123 }
00124 return nCount;
00125 case dtsCountTorrentAndActive:
00126 for ( CDownloadTransfer* pTransfer = m_pTransferFirst ; pTransfer ; pTransfer = pTransfer->m_pDlNext )
00127 {
00128 if ( VALID_TRANSFER )
00129 {
00130 switch( pTransfer->m_nState )
00131 {
00132 case dtsTorrent:
00133 case dtsRequesting:
00134 case dtsDownloading:
00135 ++nCount;
00136 }
00137 }
00138 }
00139 return nCount;
00140 default:
00141 for ( CDownloadTransfer* pTransfer = m_pTransferFirst ; pTransfer ; pTransfer = pTransfer->m_pDlNext )
00142 {
00143 if ( VALID_TRANSFER && ( pTransfer->m_nState == nState ) )
00144 {
00145 ++nCount;
00146 }
00147 }
00148 return nCount;
00149 }
00150 }
00151
00153
00154
00155 QWORD CDownloadWithTransfers::GetAmountDownloadedFrom(IN_ADDR* pAddress) const
00156 {
00157 QWORD nTotal = 0;
00158
00159 for ( CDownloadTransfer* pTransfer = m_pTransferFirst ; pTransfer ; pTransfer = pTransfer->m_pDlNext )
00160 {
00161 if ( pAddress->S_un.S_addr == pTransfer->m_pHost.sin_addr.S_un.S_addr )
00162 nTotal += pTransfer->m_nDownloaded;
00163 }
00164
00165 return nTotal;
00166 }
00167
00169
00170
00171
00172 BOOL CDownloadWithTransfers::CanStartTransfers(DWORD tNow)
00173 {
00174 if ( tNow == 0 ) tNow = GetTickCount();
00175
00176 if ( tNow - m_tTransferStart < 100 ) return FALSE;
00177 m_tTransferStart = tNow;
00178
00179
00180 if ( ! Network.ReadyToTransfer( tNow ) ) return FALSE;
00181
00182
00183 if ( Settings.Downloads.ConnectThrottle != 0 )
00184 {
00185 if ( tNow < Downloads.m_tLastConnect ) return FALSE;
00186 if ( tNow - Downloads.m_tLastConnect <= Settings.Downloads.ConnectThrottle ) return FALSE;
00187 }
00188
00189
00190 if ( Downloads.GetConnectingTransferCount() >= Settings.Downloads.MaxConnectingSources )
00191 {
00192 return FALSE;
00193 }
00194
00195 return TRUE;
00196 }
00197
00198
00199 BOOL CDownloadWithTransfers::StartTransfersIfNeeded(DWORD tNow)
00200 {
00201 if ( tNow == 0 ) tNow = GetTickCount();
00202
00203
00204 if ( ! CanStartTransfers( tNow ) ) return FALSE;
00205
00206
00207 if ( m_bBTH )
00208 {
00209
00210 if ( ( GetTransferCount( dtsCountTorrentAndActive ) ) > Settings.BitTorrent.DownloadConnections ) return FALSE;
00211 }
00212
00213 int nTransfers = GetTransferCount( dtsDownloading );
00214
00215 if ( nTransfers < Settings.Downloads.MaxFileTransfers &&
00216 ( ! Settings.Downloads.StaggardStart ||
00217 nTransfers == GetTransferCount( dtsCountAll ) ) )
00218 {
00219 if ( Downloads.m_bAllowMoreDownloads || m_pTransferFirst != NULL )
00220 {
00221 if ( Downloads.m_bAllowMoreTransfers )
00222 {
00223
00224 if ( StartNewTransfer( tNow ) )
00225 {
00226 Downloads.UpdateAllows( TRUE );
00227 return TRUE;
00228 }
00229 }
00230 }
00231 }
00232
00233 return FALSE;
00234 }
00235
00237
00238
00239 BOOL CDownloadSource::CanInitiate(BOOL bNetwork, BOOL bEstablished) const
00240 {
00241 if ( Settings.Connection.RequireForTransfers )
00242 {
00243 switch ( m_nProtocol )
00244 {
00245 case PROTOCOL_G1:
00246 if ( ! Settings.Gnutella1.EnableToday ) return FALSE;
00247 break;
00248 case PROTOCOL_G2:
00249 if ( ! Settings.Gnutella2.EnableToday ) return FALSE;
00250 break;
00251 case PROTOCOL_ED2K:
00252 if ( ! Settings.eDonkey.EnableToday ) return FALSE;
00253 if ( ! bNetwork ) return FALSE;
00254 break;
00255 case PROTOCOL_HTTP:
00256 if ( m_nGnutella == 2 )
00257 {
00258 if ( ! Settings.Gnutella2.EnableToday ) return FALSE;
00259 }
00260 else if ( m_nGnutella == 1 )
00261 {
00262 if ( ! Settings.Gnutella1.EnableToday ) return FALSE;
00263 }
00264 else
00265 {
00266 if ( ! Settings.Gnutella1.EnableToday &&
00267 ! Settings.Gnutella2.EnableToday ) return FALSE;
00268 }
00269 break;
00270 case PROTOCOL_FTP:
00271 if ( ! bNetwork ) return FALSE;
00272 break;
00273 case PROTOCOL_BT:
00274 if ( ! bNetwork ) return FALSE;
00275 break;
00276 default:
00277 theApp.Message( MSG_ERROR, _T("Source with invalid protocol found") );
00278 return FALSE;
00279 }
00280 }
00281
00282 if ( ( Settings.Connection.IgnoreOwnIP ) && ( m_pAddress.S_un.S_addr == Network.m_pHost.sin_addr.S_un.S_addr ) )
00283 return FALSE;
00284
00285 return bEstablished || Downloads.AllowMoreTransfers( (IN_ADDR*)&m_pAddress );
00286 }
00287
00289
00290
00291 BOOL CDownloadWithTransfers::StartNewTransfer(DWORD tNow)
00292 {
00293 if ( tNow == 0 ) tNow = GetTickCount();
00294
00295 BOOL bConnected = Network.IsConnected();
00296 CDownloadSource* pConnectHead = NULL;
00297 CDownloadSource* pPushHead = NULL;
00298
00299
00300 if ( ( m_bBTH ) && ( Settings.BitTorrent.PreferenceBTSources ) )
00301 {
00302 for ( CDownloadSource* pSource = m_pSourceFirst ; pSource ; )
00303 {
00304 CDownloadSource* pNext = pSource->m_pNext;
00305
00306 if ( ( pSource->m_pTransfer == NULL ) &&
00307 ( pSource->m_bPushOnly == FALSE ) &&
00308 ( pSource->m_nProtocol == PROTOCOL_BT ) &&
00309 ( pSource->m_tAttempt == 0 ) )
00310 {
00311 if ( pSource->CanInitiate( bConnected, FALSE ) )
00312 {
00313 CDownloadTransfer* pTransfer = pSource->CreateTransfer();
00314 return pTransfer != NULL && pTransfer->Initiate();
00315 }
00316 }
00317 pSource = pNext;
00318 }
00319 }
00320
00321 for ( CDownloadSource* pSource = m_pSourceFirst ; pSource ; )
00322 {
00323 CDownloadSource* pNext = pSource->m_pNext;
00324
00325 if ( pSource->m_pTransfer != NULL )
00326 {
00327
00328 }
00329 else if ( pSource->m_bPushOnly == FALSE )
00330 {
00331 if ( pSource->m_tAttempt == 0 )
00332 {
00333 if ( pSource->CanInitiate( bConnected, FALSE ) )
00334 {
00335 CDownloadTransfer* pTransfer = pSource->CreateTransfer();
00336 return pTransfer != NULL && pTransfer->Initiate();
00337 }
00338 }
00339 else if ( pSource->m_tAttempt > 0 && pSource->m_tAttempt <= tNow )
00340 {
00341 if ( pConnectHead == NULL || ( pConnectHead->m_nProtocol != PROTOCOL_HTTP && pSource->m_nProtocol == PROTOCOL_HTTP ) )
00342 {
00343 if ( pSource->CanInitiate( bConnected, FALSE ) ) pConnectHead = pSource;
00344 }
00345 }
00346 }
00347 else
00348 {
00349 if ( pSource->m_tAttempt == 0 )
00350 {
00351 if ( pPushHead == NULL && pSource->CanInitiate( bConnected, FALSE ) ) pPushHead = pSource;
00352 }
00353 else if ( pSource->m_tAttempt <= tNow )
00354 {
00355 if ( ! Settings.Downloads.NeverDrop ) pSource->Remove( TRUE, TRUE );
00356 }
00357 }
00358
00359 pSource = pNext;
00360 }
00361
00362 if ( pConnectHead != NULL )
00363 {
00364 CDownloadTransfer* pTransfer = pConnectHead->CreateTransfer();
00365 return pTransfer != NULL && pTransfer->Initiate();
00366 }
00367
00368 if ( pPushHead != NULL )
00369 {
00370 if( Network.GetStableTime() < 15 ) return FALSE;
00371 if ( pPushHead->PushRequest() ) return FALSE;
00372 if ( ! Settings.Downloads.NeverDrop ) pPushHead->Remove( TRUE, TRUE );
00373 }
00374
00375 return FALSE;
00376 }
00377
00379
00380
00381 void CDownloadWithTransfers::CloseTransfers()
00382 {
00383 BOOL bBackup = Downloads.m_bClosing;
00384 Downloads.m_bClosing = TRUE;
00385
00386 for ( CDownloadTransfer* pTransfer = m_pTransferFirst ; pTransfer ; )
00387 {
00388 CDownloadTransfer* pNext = pTransfer->m_pDlNext;
00389 pTransfer->Close( TS_TRUE );
00390 pTransfer = pNext;
00391 }
00392
00393 ASSERT( m_nTransferCount == 0 );
00394
00395 Downloads.m_bClosing = bBackup;
00396 }
00397
00399
00400
00401 DWORD CDownloadWithTransfers::GetAverageSpeed() const
00402 {
00403 DWORD nSpeed = 0;
00404
00405 for ( CDownloadTransfer* pTransfer = m_pTransferFirst ; pTransfer ; pTransfer = pTransfer->m_pDlNext )
00406 {
00407 if ( pTransfer->m_nState == dtsDownloading ) nSpeed += pTransfer->GetAverageSpeed();
00408 }
00409
00410 return nSpeed;
00411 }
00412
00414
00415
00416 DWORD CDownloadWithTransfers::GetMeasuredSpeed() const
00417 {
00418 DWORD nSpeed = 0;
00419
00420 for ( CDownloadTransfer* pTransfer = m_pTransferFirst ; pTransfer ; pTransfer = pTransfer->m_pDlNext )
00421 {
00422 if ( pTransfer->m_nState == dtsDownloading )
00423 nSpeed += pTransfer->GetMeasuredSpeed();
00424 }
00425
00426 return nSpeed;
00427 }
00428
00430
00431
00432 BOOL CDownloadWithTransfers::OnAcceptPush(GGUID* pClientID, CConnection* pConnection)
00433 {
00434 CDownload* pDownload = (CDownload*)this;
00435 if ( pDownload->IsMoving() || pDownload->IsPaused() ) return FALSE;
00436
00437 CDownloadSource* pSource = NULL;
00438
00439 for ( pSource = GetFirstSource() ; pSource ; pSource = pSource->m_pNext )
00440 {
00441 if ( pSource->m_nProtocol == PROTOCOL_HTTP && pSource->CheckPush( pClientID ) ) break;
00442 }
00443
00444 if ( pSource == NULL ) return FALSE;
00445
00446 if ( pSource->m_pTransfer != NULL )
00447 {
00448 if ( pSource->m_pTransfer->m_nState > dtsConnecting ) return FALSE;
00449 pSource->m_pTransfer->Close( TS_TRUE );
00450 }
00451
00452 if ( pConnection->m_hSocket == INVALID_SOCKET ) return FALSE;
00453
00454 CDownloadTransferHTTP* pTransfer = (CDownloadTransferHTTP*)pSource->CreateTransfer();
00455 ASSERT( pTransfer->m_nProtocol == PROTOCOL_HTTP );
00456 return pTransfer->AcceptPush( pConnection );
00457 }
00458
00460
00461
00462 BOOL CDownloadWithTransfers::OnDonkeyCallback(CEDClient* pClient, CDownloadSource* pExcept)
00463 {
00464 CDownload* pDownload = (CDownload*)this;
00465 if ( pDownload->IsMoving() || pDownload->IsPaused() ) return FALSE;
00466
00467 CDownloadSource* pSource = NULL;
00468 DWORD tNow = GetTickCount();
00469
00470 for ( pSource = GetFirstSource() ; pSource ; pSource = pSource->m_pNext )
00471 {
00472 if ( pExcept != pSource && pSource->CheckDonkey( pClient ) ) break;
00473 }
00474
00475 if ( pSource == NULL ) return FALSE;
00476
00477 if ( pSource->m_pTransfer != NULL )
00478 {
00479 if ( pSource->m_pTransfer->m_nState > dtsConnecting ) return FALSE;
00480 pSource->m_pTransfer->Close( TS_TRUE );
00481 }
00482
00483 CDownloadTransferED2K* pTransfer = (CDownloadTransferED2K*)pSource->CreateTransfer();
00484 ASSERT( pTransfer->m_nProtocol == PROTOCOL_ED2K );
00485 return pTransfer->Initiate();
00486 }
00487
00489
00490
00491 void CDownloadWithTransfers::AddTransfer(CDownloadTransfer* pTransfer)
00492 {
00493 m_nTransferCount ++;
00494 pTransfer->m_pDlPrev = m_pTransferLast;
00495 pTransfer->m_pDlNext = NULL;
00496
00497 if ( m_pTransferLast != NULL )
00498 {
00499 m_pTransferLast->m_pDlNext = pTransfer;
00500 m_pTransferLast = pTransfer;
00501 }
00502 else
00503 {
00504 m_pTransferFirst = m_pTransferLast = pTransfer;
00505 }
00506 }
00507
00508 void CDownloadWithTransfers::RemoveTransfer(CDownloadTransfer* pTransfer)
00509 {
00510 ASSERT( m_nTransferCount > 0 );
00511 m_nTransferCount --;
00512
00513 if ( pTransfer->m_pDlPrev != NULL )
00514 pTransfer->m_pDlPrev->m_pDlNext = pTransfer->m_pDlNext;
00515 else
00516 m_pTransferFirst = pTransfer->m_pDlNext;
00517
00518 if ( pTransfer->m_pDlNext != NULL )
00519 pTransfer->m_pDlNext->m_pDlPrev = pTransfer->m_pDlPrev;
00520 else
00521 m_pTransferLast = pTransfer->m_pDlPrev;
00522
00523 delete pTransfer;
00524 }