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 <limits>
00024 #include "Shareaza.h"
00025 #include "Settings.h"
00026 #include "Download.h"
00027 #include "Downloads.h"
00028 #include "DownloadSource.h"
00029 #include "DownloadTransfer.h"
00030 #include "DownloadTransferED2K.h"
00031 #include "FragmentedFile.h"
00032 #include "Datagrams.h"
00033 #include "EDClients.h"
00034 #include "EDClient.h"
00035 #include "EDPacket.h"
00036 #include "Network.h"
00037 #include "Buffer.h"
00038 #include "ED2K.h"
00039
00040 #include <zlib.h>
00041
00042 #ifdef _DEBUG
00043 #undef THIS_FILE
00044 static char THIS_FILE[]=__FILE__;
00045 #define new DEBUG_NEW
00046 #endif
00047
00048 #define BUFFER_SIZE 8192
00049
00050
00052
00053
00054 CDownloadTransferED2K::CDownloadTransferED2K(CDownloadSource* pSource) : CDownloadTransfer( pSource, PROTOCOL_ED2K )
00055 {
00056 m_pClient = NULL;
00057 m_bHashset = FALSE;
00058 m_tRequest = 0;
00059 m_tSources = 0;
00060 m_tRanking = 0;
00061 m_pAvailable = NULL;
00062 m_bUDP = FALSE;
00063
00064 m_pInflatePtr = NULL;
00065 m_pInflateBuffer = new CBuffer();
00066
00067 ASSERT( m_pDownload->m_bED2K );
00068 }
00069
00070 CDownloadTransferED2K::~CDownloadTransferED2K()
00071 {
00072 ClearRequests();
00073 delete m_pInflateBuffer;
00074
00075 if ( m_pAvailable != NULL ) delete [] m_pAvailable;
00076
00077 #ifdef _DEBUG
00078 ASSERT( m_pClient == NULL );
00079
00080 for ( CEDClient* pClient = EDClients.GetFirst() ; pClient ; pClient = pClient->m_pEdNext )
00081 {
00082 ASSERT( pClient->m_pDownload != this );
00083 }
00084 #endif
00085 }
00086
00088
00089
00090 BOOL CDownloadTransferED2K::Initiate()
00091 {
00092 ASSERT( m_pClient == NULL );
00093 ASSERT( m_nState == dtsNull );
00094
00095 if ( ! m_pDownload->m_bED2K || m_pDownload->m_nSize == SIZE_UNKNOWN )
00096 {
00097 Close( TS_FALSE );
00098 return FALSE;
00099 }
00100
00101 m_pClient = EDClients.Connect(
00102 m_pSource->m_pAddress.S_un.S_addr,
00103 m_pSource->m_nPort,
00104 m_pSource->m_nServerPort ? &m_pSource->m_pServerAddress : NULL,
00105 m_pSource->m_nServerPort,
00106 m_pSource->m_bGUID ? &m_pSource->m_pGUID : NULL );
00107
00108 if ( m_pClient == NULL )
00109 {
00110 Close( EDClients.IsFull() ? TS_TRUE : TS_FALSE );
00111 return FALSE;
00112 }
00113
00114 SetState( dtsConnecting );
00115 m_tConnected = GetTickCount();
00116
00117 if ( ! m_pClient->AttachDownload( this ) )
00118 {
00119 SetState( dtsNull );
00120 m_pClient = NULL;
00121 Close( TS_TRUE );
00122 return FALSE;
00123 }
00124
00125 m_pHost = m_pClient->m_pHost;
00126 m_sAddress = m_pClient->m_sAddress;
00127
00128 m_pClient->m_mInput.pLimit = &Downloads.m_nLimitDonkey;
00129
00130 return TRUE;
00131 }
00132
00134
00135
00136 void CDownloadTransferED2K::Close(TRISTATE bKeepSource)
00137 {
00138 SetState( dtsNull );
00139
00140 if ( m_pClient != NULL )
00141 {
00142 m_pClient->OnDownloadClose();
00143 m_pClient = NULL;
00144 }
00145
00146 CDownloadTransfer::Close( bKeepSource );
00147 }
00148
00150
00151
00152 void CDownloadTransferED2K::Boost()
00153 {
00154 if ( m_pClient == NULL ) return;
00155 m_pClient->m_mInput.pLimit = NULL;
00156 }
00157
00158 DWORD CDownloadTransferED2K::GetAverageSpeed()
00159 {
00160 return m_pSource->m_nSpeed = GetMeasuredSpeed();
00161 }
00162
00163 DWORD CDownloadTransferED2K::GetMeasuredSpeed()
00164 {
00165 if ( m_pClient == NULL ) return 0;
00166 m_pClient->Measure();
00167 return m_pClient->m_mInput.nMeasure;
00168 }
00169
00171
00172
00173 BOOL CDownloadTransferED2K::OnRun()
00174 {
00175 return OnRunEx( GetTickCount() );
00176 }
00177
00178 BOOL CDownloadTransferED2K::OnRunEx(DWORD tNow)
00179 {
00180 switch ( m_nState )
00181 {
00182 case dtsConnecting:
00183 if ( tNow > m_tConnected && tNow - m_tConnected > Settings.Connection.TimeoutConnect * 2 )
00184 {
00185 theApp.Message( MSG_ERROR, IDS_CONNECTION_TIMEOUT_CONNECT, (LPCTSTR)m_sAddress );
00186 Close( TS_TRUE );
00187 return FALSE;
00188 }
00189 break;
00190 case dtsRequesting:
00191 case dtsEnqueue:
00192 if ( tNow > m_tRequest && tNow - m_tRequest > Settings.Connection.TimeoutHandshake * 2 )
00193 {
00194 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_REQUEST_TIMEOUT, (LPCTSTR)m_sAddress );
00195 Close( TS_UNKNOWN );
00196 return FALSE;
00197 }
00198 break;
00199 case dtsQueued:
00200 return RunQueued( tNow );
00201 case dtsDownloading:
00202 case dtsHashset:
00203 if ( tNow > m_pClient->m_mInput.tLast &&
00204 tNow - m_pClient->m_mInput.tLast > Settings.Connection.TimeoutTraffic * 2 )
00205 {
00206 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_TRAFFIC_TIMEOUT, (LPCTSTR)m_sAddress );
00207 Close( TS_TRUE );
00208 return FALSE;
00209 }
00210 break;
00211 }
00212
00213 return TRUE;
00214 }
00215
00217
00218
00219 BOOL CDownloadTransferED2K::OnConnected()
00220 {
00221 ASSERT( m_pClient != NULL );
00222 ASSERT( m_pSource != NULL );
00223
00224 m_pHost = m_pClient->m_pHost;
00225 m_sAddress = m_pClient->m_sAddress;
00226
00227 m_pSource->m_bGUID = TRUE;
00228 m_pSource->m_pGUID = m_pClient->m_pGUID;
00229 m_pSource->m_sServer = m_sUserAgent = m_pClient->m_sUserAgent;
00230 m_pSource->m_sNick = m_pClient->m_sNick;
00231 m_pSource->SetLastSeen();
00232
00233 theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_CONNECTED, (LPCTSTR)m_sAddress );
00234
00235 return SendPrimaryRequest();
00236 }
00237
00239
00240
00241 void CDownloadTransferED2K::OnDropped(BOOL bError)
00242 {
00243 if ( m_nState == dtsQueued )
00244 {
00245 theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_QUEUE_DROP,
00246 (LPCTSTR)m_pDownload->GetDisplayName() );
00247 }
00248 else
00249 {
00250 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_DROPPED, (LPCTSTR)m_sAddress );
00251 Close( TS_UNKNOWN );
00252 }
00253 }
00254
00256
00257
00258 BOOL CDownloadTransferED2K::OnFileReqAnswer(CEDPacket* pPacket)
00259 {
00260 if ( m_pDownload->m_nSize <= ED2K_PART_SIZE )
00261 {
00262 if ( m_pAvailable ) delete [] m_pAvailable;
00263 m_pAvailable = new BYTE[ 1 ];
00264 m_pAvailable[ 0 ] = TRUE;
00265 m_pSource->m_oAvailable.insert( m_pSource->m_oAvailable.end(),
00266 FF::SimpleFragment( 0, m_pDownload->m_nSize ) );
00267 SendSecondaryRequest();
00268 }
00269
00270 return TRUE;
00271 }
00272
00273 BOOL CDownloadTransferED2K::OnFileNotFound(CEDPacket* pPacket)
00274 {
00275 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_FILENOTFOUND,
00276 (LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName() );
00277
00278 Close( TS_FALSE );
00279 return FALSE;
00280 }
00281
00282 BOOL CDownloadTransferED2K::OnFileStatus(CEDPacket* pPacket)
00283 {
00284 if ( m_nState <= dtsConnecting ) return TRUE;
00285
00286 if ( pPacket->GetRemaining() < sizeof(MD4) + 2 )
00287 {
00288 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00289 Close( TS_FALSE );
00290 return FALSE;
00291 }
00292
00293 MD4 pMD4;
00294 pPacket->Read( &pMD4, sizeof(MD4) );
00295
00296 if ( pMD4 != m_pDownload->m_pED2K )
00297 {
00298 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_HASH,
00299 (LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName() );
00300 return TRUE;
00301 }
00302
00303 DWORD nBlocks = pPacket->ReadShortLE();
00304
00305 if ( nBlocks == (DWORD)( ( m_pDownload->m_nSize + ED2K_PART_SIZE - 1 ) / ED2K_PART_SIZE ) )
00306 {
00307 m_pSource->m_oAvailable.clear();
00308
00309 if ( m_pAvailable != NULL ) delete [] m_pAvailable;
00310 m_pAvailable = new BYTE[ nBlocks ];
00311 ZeroMemory( m_pAvailable, nBlocks );
00312
00313 for ( DWORD nBlock = 0 ; nBlock < nBlocks && pPacket->GetRemaining() ; )
00314 {
00315 BYTE nByte = pPacket->ReadByte();
00316
00317 for ( int nBit = 0 ; nBit < 8 && nBlock < nBlocks ; nBit++, nBlock++ )
00318 {
00319 if ( nByte & ( 1 << nBit ) )
00320 {
00321 QWORD nFrom = ED2K_PART_SIZE * nBlock;
00322 QWORD nTo = nFrom + ED2K_PART_SIZE;
00323 nTo = min( nTo, m_pDownload->m_nSize );
00324
00325 m_pSource->m_oAvailable.insert( m_pSource->m_oAvailable.end(),
00326 FF::SimpleFragment( nFrom, nTo ) );
00327 m_pAvailable[ nBlock ] = TRUE;
00328 }
00329 }
00330 }
00331 }
00332 else if ( nBlocks == 0 )
00333 {
00334 m_pSource->m_oAvailable.clear();
00335
00336 if ( m_pAvailable != NULL ) delete [] m_pAvailable;
00337 m_pAvailable = NULL;
00338 }
00339 else
00340 {
00341 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00342 Close( TS_FALSE );
00343 return FALSE;
00344 }
00345
00346 SendSecondaryRequest();
00347
00348 return TRUE;
00349 }
00350
00351 BOOL CDownloadTransferED2K::OnHashsetAnswer(CEDPacket* pPacket)
00352 {
00353 if ( m_nState != dtsHashset ) return TRUE;
00354
00355 if ( pPacket->GetRemaining() < sizeof(MD4) + 2 )
00356 {
00357 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00358 Close( TS_FALSE );
00359 return FALSE;
00360 }
00361
00362 MD4 pMD4;
00363 pPacket->Read( &pMD4, sizeof(MD4) );
00364
00365 if ( pMD4 != m_pDownload->m_pED2K )
00366 {
00367 return TRUE;
00368 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_HASHSET_ERROR, (LPCTSTR)m_sAddress );
00369 Close( TS_FALSE );
00370 return FALSE;
00371 }
00372
00373 m_bHashset = TRUE;
00374
00375 DWORD nBlocks = pPacket->ReadShortLE();
00376
00377 if ( nBlocks == 0 ) nBlocks = 1;
00378
00379 if ( nBlocks != (DWORD)( ( m_pDownload->m_nSize + ED2K_PART_SIZE - 1 ) / ED2K_PART_SIZE ) )
00380 {
00381 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_HASHSET_ERROR, (LPCTSTR)m_sAddress );
00382 }
00383 else if ( m_pDownload->SetHashset( pPacket->m_pBuffer + pPacket->m_nPosition,
00384 pPacket->GetRemaining() ) )
00385 {
00386 return SendSecondaryRequest();
00387 }
00388
00389 Close( TS_FALSE );
00390 return FALSE;
00391 }
00392
00393 BOOL CDownloadTransferED2K::OnQueueRank(CEDPacket* pPacket)
00394 {
00395 if ( m_nState <= dtsConnecting ) return TRUE;
00396
00397 if ( pPacket->GetRemaining() < 4 )
00398 {
00399 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00400 Close( TS_FALSE );
00401 return FALSE;
00402 }
00403
00404 m_nQueuePos = pPacket->ReadLongLE();
00405
00406 if ( m_nQueuePos > 0 )
00407 {
00408 SetQueueRank( m_nQueuePos );
00409 }
00410 else
00411 {
00412 m_pSource->m_tAttempt = GetTickCount() + Settings.eDonkey.ReAskTime * 1000;
00413 Close( TS_UNKNOWN );
00414 }
00415
00416 return TRUE;
00417 }
00418
00419 BOOL CDownloadTransferED2K::OnRankingInfo(CEDPacket* pPacket)
00420 {
00421 if ( m_nState <= dtsConnecting ) return TRUE;
00422
00423 if ( pPacket->GetRemaining() < 12 )
00424 {
00425 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00426 Close( TS_FALSE );
00427 return FALSE;
00428 }
00429
00430 m_nQueuePos = pPacket->ReadShortLE();
00431 m_nQueueLen = pPacket->ReadShortLE();
00432
00433 SetQueueRank( m_nQueuePos );
00434
00435 return TRUE;
00436 }
00437
00438 BOOL CDownloadTransferED2K::OnFileComment(CEDPacket* pPacket)
00439 {
00440 BYTE nFileRating;
00441 DWORD nLength;
00442 CString sFileComment;
00443
00444
00445 nFileRating = pPacket->ReadByte();
00446
00447 nLength = pPacket->ReadLongLE();
00448 if ( nLength > 0 )
00449 {
00450 if ( nLength > ED2K_COMMENT_MAX ) nLength = ED2K_COMMENT_MAX;
00451
00452
00453 if ( m_pClient && m_pClient->m_bEmUnicode )
00454 sFileComment = pPacket->ReadStringUTF8( nLength );
00455 else
00456 sFileComment = pPacket->ReadString( nLength );
00457 }
00458
00459 if ( m_pDownload && m_pClient )
00460 {
00461 return m_pDownload->AddReview( &m_pClient->m_pHost.sin_addr, 3, nFileRating, m_pClient->m_sNick, sFileComment );
00462 }
00463
00464 return FALSE;
00465 }
00466
00467 BOOL CDownloadTransferED2K::OnStartUpload(CEDPacket* pPacket)
00468 {
00469 SetState( dtsDownloading );
00470 m_pClient->m_mInput.tLast = GetTickCount();
00471
00472 ClearRequests();
00473
00474 return SendFragmentRequests();
00475 }
00476
00477 BOOL CDownloadTransferED2K::OnFinishUpload(CEDPacket* pPacket)
00478 {
00479 return SendPrimaryRequest();
00480 }
00481
00482 BOOL CDownloadTransferED2K::OnSendingPart(CEDPacket* pPacket)
00483 {
00484 if ( m_nState != dtsDownloading ) return TRUE;
00485
00486 if ( pPacket->GetRemaining() <= sizeof(MD4) + 8 )
00487 {
00488 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00489 Close( TS_FALSE );
00490 return FALSE;
00491 }
00492
00493 MD4 pMD4;
00494 pPacket->Read( &pMD4, sizeof(MD4) );
00495
00496 if ( pMD4 != m_pDownload->m_pED2K )
00497 {
00498 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_HASH,
00499 (LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName() );
00500
00501
00502 return TRUE;
00503 }
00504
00505 QWORD nOffset = pPacket->ReadLongLE();
00506 QWORD nLength = pPacket->ReadLongLE();
00507
00508 if ( nLength <= nOffset )
00509 {
00510 if ( nLength == nOffset ) return TRUE;
00511 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00512 Close( TS_FALSE );
00513 return FALSE;
00514 }
00515
00516 nLength -= nOffset;
00517
00518 if ( nLength > (QWORD)pPacket->GetRemaining() )
00519 {
00520 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00521 Close( TS_FALSE );
00522 return FALSE;
00523 }
00524
00525 BOOL bUseful = m_pDownload->SubmitData( nOffset,
00526 pPacket->m_pBuffer + pPacket->m_nPosition, nLength );
00527
00528 m_oRequested.erase( FF::SimpleFragment( nOffset, nOffset + nLength ) );
00529
00530 m_pSource->AddFragment( nOffset, nLength,
00531 ( nOffset % ED2K_PART_SIZE ) ? TRUE : FALSE );
00532
00533 m_nDownloaded += nLength;
00534
00535 m_pSource->SetValid();
00536
00537 return SendFragmentRequests();
00538 }
00539
00540 BOOL CDownloadTransferED2K::OnCompressedPart(CEDPacket* pPacket)
00541 {
00542 if ( m_nState != dtsDownloading ) return TRUE;
00543
00544 if ( pPacket->GetRemaining() <= sizeof(MD4) + 8 )
00545 {
00546 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
00547 Close( TS_FALSE );
00548 return FALSE;
00549 }
00550
00551 MD4 pMD4;
00552 pPacket->Read( &pMD4, sizeof(MD4) );
00553
00554 if ( pMD4 != m_pDownload->m_pED2K )
00555 {
00556 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_HASH,
00557 (LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName() );
00558
00559
00560 return TRUE;
00561 }
00562
00563 QWORD nBaseOffset = pPacket->ReadLongLE();
00564 QWORD nBaseLength = pPacket->ReadLongLE();
00565
00566 z_streamp pStream = (z_streamp)m_pInflatePtr;
00567
00568 if ( m_pInflatePtr == NULL || m_nInflateOffset != nBaseOffset || m_nInflateLength != nBaseLength )
00569 {
00570 if ( pStream != NULL )
00571 {
00572 inflateEnd( pStream );
00573 delete pStream;
00574 }
00575
00576 m_nInflateOffset = nBaseOffset;
00577 m_nInflateLength = nBaseLength;
00578 m_nInflateRead = 0;
00579 m_nInflateWritten = 0;
00580 m_pInflateBuffer->Clear();
00581
00582 m_pInflatePtr = new z_stream;
00583 pStream = (z_streamp)m_pInflatePtr;
00584 ZeroMemory( pStream, sizeof(z_stream) );
00585
00586 if ( inflateInit( pStream ) != Z_OK )
00587 {
00588 delete pStream;
00589 m_pInflatePtr = NULL;
00590
00591 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_INFLATE_ERROR,
00592 (LPCTSTR)m_pDownload->GetDisplayName() );
00593
00594 Close( TS_FALSE );
00595 return FALSE;
00596 }
00597 }
00598
00599 m_pInflateBuffer->Add( pPacket->m_pBuffer + pPacket->m_nPosition, pPacket->GetRemaining() );
00600
00601 BYTE pBuffer[ BUFFER_SIZE ];
00602
00603 if ( m_pInflateBuffer->m_nLength > 0 && m_nInflateRead < m_nInflateLength )
00604 {
00605 pStream->next_in = m_pInflateBuffer->m_pBuffer;
00606 pStream->avail_in = m_pInflateBuffer->m_nLength;
00607
00608 do
00609 {
00610 pStream->next_out = pBuffer;
00611 pStream->avail_out = BUFFER_SIZE;
00612
00613 inflate( pStream, Z_SYNC_FLUSH );
00614
00615 if ( pStream->avail_out < BUFFER_SIZE )
00616 {
00617 QWORD nOffset = m_nInflateOffset + m_nInflateWritten;
00618 QWORD nLength = BUFFER_SIZE - pStream->avail_out;
00619
00620 BOOL bUseful = m_pDownload->SubmitData( nOffset, pBuffer, nLength );
00621
00622 m_oRequested.erase( FF::SimpleFragment( nOffset, nOffset + nLength ) );
00623
00624 m_pSource->AddFragment( nOffset, nLength,
00625 ( nOffset % ED2K_PART_SIZE ) ? TRUE : FALSE );
00626
00627 m_nDownloaded += nLength;
00628 m_nInflateWritten += nLength;
00629 }
00630 }
00631 while ( pStream->avail_out == 0 );
00632
00633 if ( pStream->avail_in >= 0 && pStream->avail_in < m_pInflateBuffer->m_nLength )
00634 {
00635 m_nInflateRead += ( m_pInflateBuffer->m_nLength - pStream->avail_in );
00636 m_pInflateBuffer->Remove( m_pInflateBuffer->m_nLength - pStream->avail_in );
00637 }
00638 }
00639
00640 if ( m_nInflateRead >= m_nInflateLength )
00641 {
00642 inflateEnd( pStream );
00643 delete pStream;
00644 m_pInflatePtr = NULL;
00645 m_pInflateBuffer->Clear();
00646 }
00647
00648 m_pSource->SetValid();
00649
00650 return SendFragmentRequests();
00651 }
00652
00654
00655
00656 void CDownloadTransferED2K::Send(CEDPacket* pPacket, BOOL bRelease)
00657 {
00658 ASSERT( m_nState > dtsConnecting );
00659 ASSERT( m_pClient != NULL );
00660 m_pClient->Send( pPacket, bRelease );
00661 }
00662
00664
00665
00666 BOOL CDownloadTransferED2K::SendPrimaryRequest()
00667 {
00668 ASSERT( m_pClient != NULL );
00669 DWORD tNow = GetTickCount();
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 SetState( dtsRequesting );
00682
00683
00684 m_tRequest = tNow;
00685
00686 ClearRequests();
00687
00688
00689 CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_FILEREQUEST );
00690 pPacket->Write( &m_pDownload->m_pED2K, sizeof(MD4) );
00691
00692 if ( Settings.eDonkey.ExtendedRequest && m_pClient->m_bEmRequest >= 1 )
00693 {
00694 m_pClient->WritePartStatus( pPacket, m_pDownload );
00695 }
00696
00697
00698
00699
00700
00701
00702
00703 Send( pPacket );
00704
00705 if ( m_pDownload->m_nSize <= ED2K_PART_SIZE )
00706 {
00707
00708 }
00709 else
00710 {
00711
00712 pPacket = CEDPacket::New( ED2K_C2C_FILESTATUSREQUEST );
00713 pPacket->Write( &m_pDownload->m_pED2K, sizeof(MD4) );
00714 Send( pPacket );
00715 }
00716
00717 if ( ( m_pDownload->GetSourceCount() < Settings.Downloads.SourcesWanted ) &&
00718 ( tNow > m_tSources ) && ( tNow - m_tSources > 30 * 60 * 1000 ) &&
00719 ( m_pClient->m_bEmule ) && ( Network.IsListening() ) )
00720 {
00721
00722 m_tSources = tNow;
00723
00724 pPacket = CEDPacket::New( ED2K_C2C_REQUESTSOURCES, ED2K_PROTOCOL_EMULE );
00725 pPacket->Write( &m_pDownload->m_pED2K, sizeof(MD4) );
00726 Send( pPacket );
00727 }
00728
00729 return TRUE;
00730 }
00731
00732 BOOL CDownloadTransferED2K::SendSecondaryRequest()
00733 {
00734 ASSERT( m_pClient != NULL );
00735 ASSERT( m_nState > dtsConnecting );
00736
00737
00738 if ( ! m_pDownload->PrepareFile() )
00739 {
00740 Close( TS_TRUE );
00741 return FALSE;
00742 }
00743
00744 if ( m_bHashset == FALSE && m_pDownload->NeedHashset() )
00745 {
00746 CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_HASHSETREQUEST );
00747 pPacket->Write( &m_pDownload->m_pED2K, sizeof(MD4) );
00748 Send( pPacket );
00749
00750 SetState( dtsHashset );
00751 m_pClient->m_mInput.tLast = GetTickCount();
00752 }
00753 else if ( m_pSource->HasUsefulRanges() )
00754 {
00755 CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_QUEUEREQUEST );
00756 pPacket->Write( &m_pDownload->m_pED2K, sizeof(MD4) );
00757 Send( pPacket );
00758
00759 SetState( dtsEnqueue );
00760 m_tRequest = GetTickCount();
00761 }
00762 else
00763 {
00764 m_pSource->m_tAttempt = GetTickCount() + Settings.eDonkey.ReAskTime * 500;
00765 m_pSource->SetAvailableRanges( NULL );
00766 theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_FRAGMENT_END, (LPCTSTR)m_sAddress );
00767 Close( TS_TRUE );
00768 return FALSE;
00769 }
00770
00771 ClearRequests();
00772
00773 return TRUE;
00774 }
00775
00777
00778
00779 BOOL CDownloadTransferED2K::SendFragmentRequests()
00780 {
00781 ASSERT( m_nState == dtsDownloading );
00782 ASSERT( m_pClient != NULL );
00783
00784 if ( m_oRequested.size() >= (int)Settings.eDonkey.RequestPipe ) return TRUE;
00785
00786 FF::SimpleFragmentList oPossible( m_pDownload->GetEmptyFragmentList() );
00787
00788 if ( ! m_pDownload->m_bTorrentEndgame )
00789 {
00790 for ( CDownloadTransfer* pTransfer = m_pDownload->GetFirstTransfer() ; pTransfer && !oPossible.empty() ; pTransfer = pTransfer->m_pDlNext )
00791 {
00792 pTransfer->SubtractRequested( oPossible );
00793 }
00794 }
00795
00796 while ( m_oRequested.size() < (int)Settings.eDonkey.RequestPipe )
00797 {
00798 QWORD nOffset, nLength;
00799
00800 if ( SelectFragment( oPossible, nOffset, nLength ) )
00801 {
00802 ChunkifyRequest( &nOffset, &nLength, Settings.eDonkey.RequestSize, FALSE );
00803
00804 FF::SimpleFragment Selected( nOffset, nOffset + nLength );
00805 oPossible.erase( Selected );
00806
00807 m_oRequested.pushBack( Selected );
00808
00809 CEDPacket* pPacket = CEDPacket::New( ED2K_C2C_REQUESTPARTS );
00810 pPacket->Write( &m_pDownload->m_pED2K, sizeof(MD4) );
00811 pPacket->WriteLongLE( (DWORD)nOffset );
00812 pPacket->WriteLongLE( 0 );
00813 pPacket->WriteLongLE( 0 );
00814 pPacket->WriteLongLE( (DWORD)( nOffset + nLength ) );
00815 pPacket->WriteLongLE( 0 );
00816 pPacket->WriteLongLE( 0 );
00817 Send( pPacket );
00818
00819 int nType = ( m_nDownloaded == 0 || ( nOffset % ED2K_PART_SIZE ) == 0 )
00820 ? MSG_DEFAULT : MSG_DEBUG;
00821
00822 theApp.Message( nType, IDS_DOWNLOAD_FRAGMENT_REQUEST,
00823 nOffset, nOffset + nLength - 1,
00824 (LPCTSTR)m_pDownload->GetDisplayName(), (LPCTSTR)m_sAddress );
00825 }
00826 else
00827 {
00828 break;
00829 }
00830 }
00831
00832
00833 if ( oPossible.empty() && Settings.eDonkey.Endgame && ! m_pDownload->m_bTorrentEndgame )
00834 {
00835
00836 if ( ( m_pDownload->GetVolumeComplete() > 100*1024*1024 ) &&
00837 ( m_pDownload->GetVolumeRemaining() < 1*1024*1024 ) )
00838 {
00839
00840 m_pDownload->m_bTorrentEndgame = TRUE;
00841 theApp.Message( MSG_DEBUG, _T("Activating endgame for ed2k transfer %s"), m_pDownload->m_sLocalName );
00842 }
00843 }
00844
00845 if ( !m_oRequested.empty() ) return TRUE;
00846
00847 Send( CEDPacket::New( ED2K_C2C_QUEUERELEASE ) );
00848
00849 theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_FRAGMENT_END, (LPCTSTR)m_sAddress );
00850 Close( TS_TRUE );
00851
00852 return FALSE;
00853 }
00854
00855 void CDownloadTransferED2K::ClearRequests()
00856 {
00857 m_oRequested.clear();
00858
00859 if ( z_streamp pStream = (z_streamp)m_pInflatePtr )
00860 {
00861 inflateEnd( pStream );
00862 delete pStream;
00863 m_pInflatePtr = NULL;
00864 m_pInflateBuffer->Clear();
00865 }
00866 }
00867
00869
00870
00871 BOOL CDownloadTransferED2K::SelectFragment(const FF::SimpleFragmentList& oPossible, QWORD& nOffset, QWORD& nLength)
00872 {
00873 FF::SimpleFragment oSelection( selectBlock( oPossible,
00874 ED2K_PART_SIZE, m_pAvailable ) );
00875
00876 if ( oSelection.end() == ::std::numeric_limits< FF::SimpleFragment::SizeType >::max() ) return FALSE;
00877
00878 nOffset = oSelection.begin();
00879 nLength = oSelection.length();
00880
00881 return TRUE;
00882 }
00883
00885
00886
00887 BOOL CDownloadTransferED2K::SubtractRequested(FF::SimpleFragmentList& ppFragments)
00888 {
00889 if ( m_nState != dtsDownloading ) return FALSE;
00890 ppFragments.erase( m_oRequested.begin(), m_oRequested.end() );
00891 return TRUE;
00892 }
00893
00895
00896
00897 BOOL CDownloadTransferED2K::RunQueued(DWORD tNow)
00898 {
00899 ASSERT( m_pClient != NULL );
00900 ASSERT( m_nState == dtsQueued );
00901
00902 if ( Settings.Downloads.QueueLimit > 0 && m_nQueuePos > Settings.Downloads.QueueLimit )
00903 {
00904 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_QUEUE_HUGE,
00905 (LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName(), m_nQueuePos );
00906 Close( TS_FALSE );
00907 return FALSE;
00908 }
00909 else if ( m_pClient->m_bConnected == FALSE && tNow > m_tRanking && tNow - m_tRanking > Settings.eDonkey.ReAskTime * 1000 + 20000 )
00910 {
00911 theApp.Message( MSG_ERROR, IDS_DOWNLOAD_QUEUE_TIMEOUT,
00912 (LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName() );
00913 Close( TS_UNKNOWN );
00914 return FALSE;
00915 }
00916 else if ( m_pClient->m_nUDP > 0 && ! m_bUDP && tNow > m_tRequest && tNow - m_tRequest > Settings.eDonkey.ReAskTime * 1000 - 20000 )
00917 {
00918 CEDPacket* pPing = CEDPacket::New( ED2K_C2C_UDP_REASKFILEPING, ED2K_PROTOCOL_EMULE );
00919 pPing->Write( &m_pDownload->m_pED2K, sizeof(MD4) );
00920 Datagrams.Send( &m_pClient->m_pHost.sin_addr, m_pClient->m_nUDP, pPing );
00921 m_bUDP = TRUE;
00922 }
00923 else if ( tNow > m_tRequest && tNow - m_tRequest > Settings.eDonkey.ReAskTime * 1000 )
00924 {
00925 m_tRequest = GetTickCount();
00926
00927 if ( m_pClient->IsOnline() )
00928 {
00929 return OnConnected();
00930 }
00931 else
00932 {
00933 m_pClient->Connect();
00934 }
00935 }
00936
00937 return TRUE;
00938 }
00939
00941
00942
00943 void CDownloadTransferED2K::SetQueueRank(int nRank)
00944 {
00945 SetState( dtsQueued );
00946
00947 m_tRequest = m_tRanking = GetTickCount();
00948 m_nQueuePos = nRank;
00949 m_bUDP = FALSE;
00950
00951 ClearRequests();
00952
00953 theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_QUEUED,
00954 (LPCTSTR)m_sAddress, m_nQueuePos, m_nQueueLen, _T("eDonkey2000") );
00955 }