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 "Network.h"
00026 #include "Neighbours.h"
00027 #include "EDNeighbour.h"
00028 #include "EDClient.h"
00029 #include "EDClients.h"
00030 #include "EDPacket.h"
00031 #include "GProfile.h"
00032 #include "HostCache.h"
00033 #include "ED2K.h"
00034
00035 #include "Library.h"
00036 #include "SharedFile.h"
00037 #include "Download.h"
00038 #include "Downloads.h"
00039 #include "DownloadSource.h"
00040 #include "DownloadTransferED2K.h"
00041 #include "UploadTransferED2K.h"
00042 #include "SourceURL.h"
00043
00044 #include "ChatCore.h"
00045 #include "Security.h"
00046 #include "UploadQueues.h"
00047
00048 #ifdef _DEBUG
00049 #undef THIS_FILE
00050 static char THIS_FILE[]=__FILE__;
00051 #define new DEBUG_NEW
00052 #endif
00053
00054
00056
00057
00058 CEDClient::CEDClient()
00059 {
00060 m_pEdPrev = NULL;
00061 m_pEdNext = NULL;
00062
00063 m_bGUID = FALSE;
00064 m_pGUID = (GGUID&)GUID_NULL;
00065 m_nClientID = 0;
00066 m_nUDP = 0;
00067
00068
00069 m_bEmule = FALSE;
00070 m_nEmVersion = 0;
00071 m_nEmCompatible = 0;
00072 m_nSoftwareVersion=0;
00073
00074
00075 m_bEmAICH = FALSE;
00076 m_bEmUnicode = FALSE;
00077 m_bEmUDPVersion = FALSE;
00078 m_bEmDeflate = FALSE;
00079 m_bEmSecureID = FALSE;
00080 m_bEmSources = FALSE;
00081 m_bEmRequest = FALSE;
00082 m_bEmComments = FALSE;
00083 m_bEmPeerCache = FALSE;
00084 m_bEmBrowse = FALSE;
00085 m_bEmMultiPacket= FALSE;
00086 m_bEmPreview = FALSE;
00087
00088
00089 m_bLogin = FALSE;
00090 m_bUpMD4 = FALSE;
00091
00092 m_pDownload = NULL;
00093 m_pUpload = NULL;
00094 m_bSeeking = FALSE;
00095 m_nRunExCookie = 0;
00096
00097 m_bOpenChat = FALSE;
00098 m_bCommentSent = FALSE;
00099
00100 m_mInput.pLimit = &Settings.Bandwidth.Request;
00101 m_mOutput.pLimit = &Settings.Bandwidth.Request;
00102
00103 EDClients.Add( this );
00104 }
00105
00106 CEDClient::~CEDClient()
00107 {
00108 ASSERT( m_hSocket == INVALID_SOCKET );
00109 ASSERT( m_pUpload == NULL );
00110 ASSERT( m_pDownload == NULL );
00111
00112 EDClients.Remove( this );
00113 }
00114
00116
00117
00118 BOOL CEDClient::ConnectTo(DWORD nClientID, WORD nClientPort, IN_ADDR* pServerAddress, WORD nServerPort, GGUID* pGUID)
00119 {
00120 ASSERT( m_nClientID == 0 );
00121
00122 m_nClientID = nClientID;
00123 if ( m_bGUID = ( pGUID != NULL ) ) m_pGUID = *pGUID;
00124
00125 m_pHost.sin_family = AF_INET;
00126 m_pHost.sin_addr = (IN_ADDR&)nClientID;
00127 m_pHost.sin_port = htons( nClientPort );
00128
00129 if ( pServerAddress != NULL && nServerPort != 0 )
00130 {
00131 m_pServer.sin_family = AF_INET;
00132 m_pServer.sin_addr = *pServerAddress;
00133 m_pServer.sin_port = htons( nServerPort );
00134 }
00135 else
00136 {
00137 ZeroMemory( &m_pServer, sizeof(m_pServer) );
00138 }
00139
00140 return TRUE;
00141 }
00142
00144
00145
00146 BOOL CEDClient::Equals(CEDClient* pClient)
00147 {
00148 ASSERT( this != NULL );
00149 ASSERT( pClient != NULL );
00150
00151 if ( m_bGUID && pClient->m_bGUID ) return m_pGUID == pClient->m_pGUID;
00152
00153 if ( CEDPacket::IsLowID( m_nClientID ) &&
00154 CEDPacket::IsLowID( pClient->m_nClientID ) )
00155 {
00156 return ( m_pServer.sin_addr.S_un.S_addr == pClient->m_pServer.sin_addr.S_un.S_addr ) &&
00157 ( m_nClientID == pClient->m_nClientID );
00158 }
00159
00160 return m_pHost.sin_addr.S_un.S_addr == pClient->m_pHost.sin_addr.S_un.S_addr;
00161 }
00162
00164
00165
00166 BOOL CEDClient::Connect()
00167 {
00168 if ( m_hSocket != INVALID_SOCKET ) return FALSE;
00169 if ( EDClients.IsFull( this ) )
00170 {
00171
00172 if ( ! m_pDownload || m_pDownload->m_nState != dtsQueued ) return FALSE;
00173
00174
00175 if ( EDClients.IsOverloaded() )
00176 {
00177 theApp.Message( MSG_ERROR, _T("ED2K Queued download was dropped due to connection overloading") );
00178 return FALSE;
00179 }
00180 }
00181
00182 if ( CEDPacket::IsLowID( m_nClientID ) )
00183 {
00184 if ( ! Neighbours.PushDonkey( m_nClientID, &m_pServer.sin_addr, htons( m_pServer.sin_port ) ) ) return FALSE;
00185 m_tConnected = GetTickCount();
00186 }
00187 else
00188 {
00189 if ( ! CConnection::ConnectTo( &m_pHost ) ) return FALSE;
00190 theApp.Message( MSG_DEFAULT, IDS_ED2K_CLIENT_CONNECTING, (LPCTSTR)m_sAddress );
00191 }
00192
00193 return TRUE;
00194 }
00195
00197
00198
00199 void CEDClient::Remove()
00200 {
00201 ASSERT( this != NULL );
00202
00203 m_bGUID = TRUE;
00204 Close();
00205
00206 DetachUpload();
00207 DetachDownload();
00208
00209 Close();
00210
00211 if ( Settings.General.Debug && Settings.General.DebugLog ) theApp.Message( MSG_DEBUG, _T("CEDClient::Remove(): %x"), this );
00212
00213 delete this;
00214 }
00215
00217
00218
00219 void CEDClient::Merge(CEDClient* pClient)
00220 {
00221 ASSERT( pClient != NULL );
00222
00223 if ( pClient->m_pDownload != NULL )
00224 {
00225 DetachDownload();
00226 m_pDownload = pClient->m_pDownload;
00227 m_pDownload->m_pClient = this;
00228 pClient->m_pDownload = NULL;
00229 }
00230
00231 if ( pClient->m_pUpload != NULL )
00232 {
00233 DetachUpload();
00234 m_pUpload = pClient->m_pUpload;
00235 m_pUpload->m_pClient = this;
00236 pClient->m_pUpload = NULL;
00237 }
00238
00239
00240 if ( ( pClient->m_mInput.pLimit = &Downloads.m_nLimitDonkey ) ||
00241 ( m_mInput.pLimit = &Downloads.m_nLimitDonkey ) )
00242 {
00243 m_mInput.pLimit = &Downloads.m_nLimitDonkey;
00244 }
00245 else
00246 {
00247 m_mInput.pLimit = &Settings.Bandwidth.Request;
00248 }
00249
00250 if ( ( pClient->m_mOutput.pLimit != &Settings.Bandwidth.Request ) &&
00251 ( pClient->m_mOutput.pLimit != NULL ) )
00252 {
00253 m_mOutput.pLimit = pClient->m_mOutput.pLimit;
00254 }
00255 else if ( m_mOutput.pLimit == NULL )
00256 {
00257 m_mOutput.pLimit = &Settings.Bandwidth.Request;
00258 }
00259
00260
00261 if ( ! m_bOpenChat ) m_bOpenChat = pClient->m_bOpenChat;
00262 if ( ! m_bCommentSent ) m_bCommentSent = pClient->m_bCommentSent;
00263
00264
00265 if ( ! m_nEmVersion ) m_nEmVersion = pClient->m_nEmVersion;
00266 if ( ! m_nEmCompatible ) m_nEmCompatible = pClient->m_nEmCompatible;
00267 if ( ! m_nSoftwareVersion ) m_nSoftwareVersion = pClient->m_nSoftwareVersion;
00268 if ( ! m_bEmAICH ) m_bEmAICH = pClient->m_bEmAICH;
00269 if ( ! m_bEmUnicode ) m_bEmUnicode = pClient->m_bEmUnicode;
00270 if ( ! m_bEmUDPVersion ) m_bEmUDPVersion = pClient->m_bEmUDPVersion;
00271 if ( ! m_bEmDeflate ) m_bEmDeflate = pClient->m_bEmDeflate;
00272 if ( ! m_bEmSecureID ) m_bEmSecureID = pClient->m_bEmSecureID;
00273 if ( ! m_bEmSources ) m_bEmSources = pClient->m_bEmSources;
00274 if ( ! m_bEmRequest ) m_bEmRequest = pClient->m_bEmRequest;
00275 if ( ! m_bEmComments ) m_bEmComments = pClient->m_bEmComments;
00276 if ( ! m_bEmPeerCache ) m_bEmPeerCache = pClient->m_bEmPeerCache;
00277 if ( ! m_bEmBrowse ) m_bEmBrowse = pClient->m_bEmBrowse;
00278 if ( ! m_bEmMultiPacket ) m_bEmMultiPacket = pClient->m_bEmMultiPacket;
00279 if ( ! m_bEmPreview ) m_bEmPreview = pClient->m_bEmPreview;
00280 }
00281
00283
00284
00285 void CEDClient::Send(CEDPacket* pPacket, BOOL bRelease)
00286 {
00287 if ( pPacket != NULL )
00288 {
00289 ASSERT( pPacket->m_nProtocol == PROTOCOL_ED2K );
00290 ASSERT( pPacket->m_nEdProtocol == ED2K_PROTOCOL_EDONKEY || m_bEmule || pPacket->m_nType == ED2K_C2C_EMULEINFO );
00291
00292 if ( m_hSocket != INVALID_SOCKET )
00293 {
00294
00295 pPacket->ToBuffer( m_pOutput );
00296 OnWrite();
00297 }
00298
00299 if ( bRelease ) pPacket->Release();
00300 }
00301 else if ( m_hSocket != INVALID_SOCKET )
00302 {
00303 OnWrite();
00304 }
00305 }
00306
00308
00309
00310 void CEDClient::AttachTo(CConnection* pConnection)
00311 {
00312 ASSERT( m_hSocket == INVALID_SOCKET );
00313 CTransfer::AttachTo( pConnection );
00314 theApp.Message( MSG_DEFAULT, IDS_ED2K_CLIENT_ACCEPTED, (LPCTSTR)m_sAddress );
00315 }
00316
00318
00319
00320 void CEDClient::Close()
00321 {
00322 ASSERT( this != NULL );
00323 CTransfer::Close();
00324 m_bConnected = m_bLogin = FALSE;
00325
00326 if ( ( m_pDownload ) && ( m_pDownload->m_nState == dtsDownloading ) )
00327 {
00328 theApp.Message( MSG_ERROR, _T("Warning: CEDClient::Close() called for downloading client %s"), m_sAddress );
00329 m_pDownload->SetState( dtsNull );
00330 }
00331
00332 }
00333
00335
00336
00337 BOOL CEDClient::AttachDownload(CDownloadTransferED2K* pDownload)
00338 {
00339 if ( m_pDownload != NULL ) return FALSE;
00340 m_pDownload = pDownload;
00341
00342 if ( m_bLogin )
00343 return m_pDownload->OnConnected();
00344 else if ( m_hSocket == INVALID_SOCKET )
00345 Connect();
00346
00347 return TRUE;
00348 }
00349
00350 void CEDClient::OnDownloadClose()
00351 {
00352 CDownloadSource* pExcept = m_pDownload ? m_pDownload->m_pSource : NULL;
00353 m_pDownload = NULL;
00354 m_mInput.pLimit = &Settings.Bandwidth.Request;
00355 SeekNewDownload( pExcept );
00356 }
00357
00358 BOOL CEDClient::SeekNewDownload(CDownloadSource* pExcept)
00359 {
00360
00361 return FALSE;
00362
00363 if ( m_pDownload != NULL ) return FALSE;
00364 if ( m_bSeeking ) return FALSE;
00365 m_bSeeking = TRUE;
00366 BOOL bSeek = Downloads.OnDonkeyCallback( this, pExcept );
00367 m_bSeeking = FALSE;
00368 return bSeek;
00369 }
00370
00371 void CEDClient::DetachDownload()
00372 {
00373 m_bSeeking = TRUE;
00374 if ( m_pDownload != NULL ) m_pDownload->Close( TS_UNKNOWN );
00375 ASSERT( m_pDownload == NULL );
00376 m_bSeeking = FALSE;
00377 }
00378
00379 void CEDClient::OnUploadClose()
00380 {
00381 m_pUpload = NULL;
00382 m_mOutput.pLimit = &Settings.Bandwidth.Request;
00383 }
00384
00385 void CEDClient::DetachUpload()
00386 {
00387 if ( m_pUpload != NULL ) m_pUpload->Close();
00388 ASSERT( m_pUpload == NULL );
00389 }
00390
00392
00393
00394 BOOL CEDClient::OnRun()
00395 {
00396
00397
00398 DWORD tNow = GetTickCount();
00399
00400 if ( ! m_bConnected )
00401 {
00402 if ( tNow - m_tConnected > Settings.Connection.TimeoutConnect )
00403 {
00404 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_CONNECT_TIMEOUT, (LPCTSTR)m_sAddress );
00405 NotifyDropped();
00406 Close();
00407 return FALSE;
00408 }
00409 }
00410 else if ( ! m_bLogin )
00411 {
00412 if ( tNow - m_tConnected > Settings.Connection.TimeoutHandshake )
00413 {
00414
00415 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_HANDSHAKE_TIMEOUT, (LPCTSTR)m_sAddress );
00416 NotifyDropped();
00417 Close();
00418 return FALSE;
00419 }
00420 }
00421 else
00422 {
00423 if ( m_bOpenChat )
00424 {
00425
00426 if ( Settings.Community.ChatEnable ) ChatCore.OnED2KMessage( this, NULL );
00427 m_bOpenChat = FALSE;
00428 }
00429 else if ( tNow - m_mInput.tLast > Settings.Connection.TimeoutTraffic &&
00430 tNow - m_mOutput.tLast > Settings.Connection.TimeoutTraffic )
00431 {
00432
00433 if ( ( m_pDownload ) && ( m_pDownload->m_nState == dtsDownloading ) )
00434 return TRUE;
00435
00436 theApp.Message( MSG_DEFAULT, IDS_ED2K_CLIENT_CLOSED, (LPCTSTR)m_sAddress );
00437 Close();
00438 return FALSE;
00439 }
00440 }
00441
00442 return TRUE;
00443 }
00444
00445 void CEDClient::OnRunEx(DWORD tNow)
00446 {
00447 if ( m_pDownload != NULL )
00448 {
00449 m_pDownload->OnRunEx( tNow );
00450 if ( m_pUpload != NULL ) m_pUpload->OnRunEx( tNow );
00451 }
00452 else if ( m_pUpload != NULL )
00453 {
00454 m_pUpload->OnRunEx( tNow );
00455 }
00456 else if ( m_hSocket == INVALID_SOCKET )
00457 {
00458
00459
00460 if ( m_bOpenChat )
00461 {
00462
00463 DWORD tNow = GetTickCount();
00464 if ( tNow - m_tConnected < Settings.Connection.TimeoutHandshake ) return;
00465 }
00466
00467 Remove();
00468 }
00469 }
00470
00472
00473
00474 BOOL CEDClient::OnConnected()
00475 {
00476 SendHello( ED2K_C2C_HELLO );
00477 return TRUE;
00478 }
00479
00481
00482
00483 void CEDClient::OnDropped(BOOL bError)
00484 {
00485 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_DROPPED, (LPCTSTR)m_sAddress );
00486 NotifyDropped( bError );
00487 Close();
00488 }
00489
00490 void CEDClient::NotifyDropped(BOOL bError)
00491 {
00492 m_bSeeking = TRUE;
00493 if ( m_pDownload != NULL ) m_pDownload->OnDropped( bError );
00494 if ( m_pUpload != NULL ) m_pUpload->OnDropped( bError );
00495 m_bSeeking = FALSE;
00496 }
00497
00499
00500
00501 BOOL CEDClient::OnWrite()
00502 {
00503 CTransfer::OnWrite();
00504 return TRUE;
00505 }
00506
00508
00509
00510 BOOL CEDClient::OnRead()
00511 {
00512 BOOL bSuccess = TRUE;
00513 CEDPacket* pPacket;
00514
00515 CTransfer::OnRead();
00516
00517 while ( pPacket = CEDPacket::ReadBuffer( m_pInput, ED2K_PROTOCOL_EMULE ) )
00518 {
00519 try
00520 {
00521 bSuccess = OnPacket( pPacket );
00522 }
00523 catch ( CException* pException )
00524 {
00525 pException->Delete();
00526 if ( ! m_bGUID ) bSuccess = FALSE;
00527 }
00528
00529 pPacket->Release();
00530 if ( ! bSuccess ) break;
00531 }
00532
00533 return bSuccess;
00534 }
00535
00537
00538
00539 BOOL CEDClient::OnLoggedIn()
00540 {
00541 m_bLogin = TRUE;
00542
00543 EDClients.Merge( this );
00544
00545 if ( m_pDownload != NULL )
00546 {
00547 m_pDownload->OnConnected();
00548 }
00549 else
00550 {
00551 SeekNewDownload();
00552 }
00553
00554 if ( m_pUpload != NULL ) m_pUpload->OnConnected();
00555
00556 return TRUE;
00557 }
00558
00560
00561
00562 BOOL CEDClient::OnPacket(CEDPacket* pPacket)
00563 {
00564
00565
00566 if ( pPacket->m_nEdProtocol == ED2K_PROTOCOL_EDONKEY )
00567 {
00568 switch ( pPacket->m_nType )
00569 {
00570
00571
00572 case ED2K_C2C_HELLO:
00573 if ( pPacket->GetRemaining() ) pPacket->ReadByte();
00574 return OnHello( pPacket );
00575 case ED2K_C2C_HELLOANSWER:
00576 return OnHello( pPacket );
00577
00578
00579
00580 case ED2K_C2C_FILEREQUEST:
00581 return OnFileRequest( pPacket );
00582 case ED2K_C2C_FILESTATUSREQUEST:
00583 return OnFileStatusRequest( pPacket );
00584 case ED2K_C2C_HASHSETREQUEST:
00585 return OnHashsetRequest( pPacket );
00586 case ED2K_C2C_QUEUEREQUEST:
00587 return OnQueueRequest( pPacket );
00588 case ED2K_C2C_QUEUERELEASE:
00589 if ( m_pUpload != NULL ) m_pUpload->OnQueueRelease( pPacket );
00590 return TRUE;
00591 case ED2K_C2C_REQUESTPARTS:
00592 if ( m_pUpload != NULL ) m_pUpload->OnRequestParts( pPacket );
00593 return TRUE;
00594
00595
00596
00597 case ED2K_C2C_FILEREQANSWER:
00598 if ( m_pDownload != NULL ) m_pDownload->OnFileReqAnswer( pPacket );
00599 return TRUE;
00600 case ED2K_C2C_FILENOTFOUND:
00601 if ( m_pDownload != NULL ) m_pDownload->OnFileNotFound( pPacket );
00602 return TRUE;
00603 case ED2K_C2C_FILESTATUS:
00604 if ( m_pDownload != NULL ) m_pDownload->OnFileStatus( pPacket );
00605 return TRUE;
00606 case ED2K_C2C_HASHSETANSWER:
00607 if ( m_pDownload != NULL ) m_pDownload->OnHashsetAnswer( pPacket );
00608 return TRUE;
00609 case ED2K_C2C_QUEUERANK:
00610 if ( m_pDownload != NULL ) m_pDownload->OnQueueRank( pPacket );
00611 return TRUE;
00612 case ED2K_C2C_STARTUPLOAD:
00613 if ( m_pDownload != NULL ) m_pDownload->OnStartUpload( pPacket );
00614 return TRUE;
00615 case ED2K_C2C_FINISHUPLOAD:
00616 if ( m_pDownload != NULL ) m_pDownload->OnFinishUpload( pPacket );
00617 return TRUE;
00618 case ED2K_C2C_SENDINGPART:
00619 if ( m_pDownload != NULL ) m_pDownload->OnSendingPart( pPacket );
00620 return TRUE;
00621
00622
00623 case ED2K_C2C_MESSAGE:
00624 return OnMessage( pPacket );
00625
00626 default:
00627 CString str;
00628 str.Format( _T("Unrecognised packet - IP: %s - edonkey - type: 0x%x - in CEDClient::OnPacket"),
00629 LPCTSTR( m_sAddress ), int( pPacket->m_nType ) );
00630 theApp.Message( MSG_DEBUG, LPCTSTR( str ) );
00631 }
00632 }
00633 else if ( pPacket->m_nEdProtocol == ED2K_PROTOCOL_EMULE )
00634 {
00635 switch ( pPacket->m_nType )
00636 {
00637 case ED2K_C2C_EMULEINFO:
00638 return OnEmuleInfo( pPacket );
00639 case ED2K_C2C_EMULEINFOANSWER:
00640 return OnEmuleInfo( pPacket );
00641
00642 case ED2K_C2C_COMPRESSEDPART:
00643 if ( m_pDownload != NULL ) m_pDownload->OnCompressedPart( pPacket );
00644 return TRUE;
00645 case ED2K_C2C_QUEUERANKING:
00646 if ( m_pDownload != NULL ) m_pDownload->OnRankingInfo( pPacket );
00647 return TRUE;
00648 case ED2K_C2C_FILEDESC:
00649 if ( m_pDownload != NULL ) m_pDownload->OnFileComment( pPacket );
00650 return TRUE;
00651
00652 case ED2K_C2C_REQUESTSOURCES:
00653 return OnSourceRequest( pPacket );
00654 case ED2K_C2C_ANSWERSOURCES:
00655 return OnSourceAnswer( pPacket );
00656
00657 default:
00658 CString str;
00659 str.Format( _T("Unrecognised packet - IP: %s - emule - type: 0x%x - in CEDClient::OnPacket"),
00660 LPCTSTR( m_sAddress ), int( pPacket->m_nType ) );
00661 theApp.Message( MSG_DEBUG, LPCTSTR( str ) );
00662 }
00663 }
00664
00665 return TRUE;
00666 }
00667
00669
00670
00671 BOOL CEDClient::SendCommentsPacket(int nRating, LPCTSTR pszComments)
00672 {
00673
00674 if ( ( ! m_bCommentSent ) && ( m_bEmComments > 0 ) && ( m_bEmule ) )
00675 {
00676
00677 CString strComments = pszComments;
00678 strComments.Replace( '\n', ' ' );
00679 strComments.Replace( '\r', ' ' );
00680 strComments.Trim();
00681
00682
00683 if ( ( nRating > 0 ) || ( strComments.GetLength() ) )
00684 {
00685
00686 CEDPacket* pComment = CEDPacket::New( ED2K_C2C_FILEDESC, ED2K_PROTOCOL_EMULE );
00687 pComment->WriteByte( (BYTE)min( nRating, 5 ) );
00688 pComment->WriteLongEDString( strComments.Left(ED2K_COMMENT_MAX), m_bEmUnicode );
00689
00690
00691 theApp.Message( MSG_DEBUG, _T("Sending file comments to %s"), m_sAddress );
00692 m_bCommentSent = TRUE;
00693 Send( pComment );
00694
00695 return TRUE;
00696 }
00697 }
00698 return FALSE;
00699 }
00700
00702
00703
00704 void CEDClient::SendHello(BYTE nType)
00705 {
00706 CEDPacket* pPacket = CEDPacket::New( nType );
00707
00708 if ( nType == ED2K_C2C_HELLO ) pPacket->WriteByte( 0x10 );
00709
00710 CEDNeighbour* pServer = Neighbours.GetDonkeyServer();
00711
00712 GGUID pGUID = MyProfile.GUID;
00713 pGUID.n[5] = 14;
00714 pGUID.n[14] = 111;
00715 pPacket->Write( &pGUID, 16 );
00716
00717 pPacket->WriteLongLE( pServer ? pServer->m_nClientID : Network.m_pHost.sin_addr.S_un.S_addr );
00718 pPacket->WriteShortLE( htons( Network.m_pHost.sin_port ) );
00719
00720 pPacket->WriteLongLE( 5 );
00721
00722
00723 CString strNick = MyProfile.GetNick();
00724
00725 if ( Settings.eDonkey.TagNames )
00726 {
00727 if ( strNick.GetLength() )
00728 strNick += _T(" (shareaza.com)");
00729 else
00730 strNick = _T("www.shareaza.com");
00731 }
00732 strNick.Left( 255 );
00733
00734 CEDTag( ED2K_CT_NAME, strNick ).Write( pPacket, ED2K_SERVER_TCP_UNICODE );
00735
00736
00737 CEDTag( ED2K_CT_VERSION, ED2K_VERSION ).Write( pPacket );
00738
00739
00740
00741
00742
00743 DWORD nVersion = ( ( ( ED2K_COMPATIBLECLIENT_ID & 0xFF ) << 24 ) |
00744 ( ( theApp.m_nVersion[0] & 0x7F ) << 17 ) |
00745 ( ( theApp.m_nVersion[1] & 0x7F ) << 10 ) |
00746 ( ( theApp.m_nVersion[2] & 0x07 ) << 7 ) |
00747 ( ( theApp.m_nVersion[3] & 0x7F ) ) );
00748
00749 CEDTag( ED2K_CT_SOFTWAREVERSION, nVersion ).Write( pPacket );
00750
00751
00752 BYTE nExtendedRequests = ( Settings.eDonkey.ExtendedRequest ) ? ED2K_VERSION_EXTENDEDREQUEST : 0 ;
00753 nVersion = ( ( ED2K_VERSION_AICH << 29) |
00754 ( TRUE << 28) |
00755 ( ED2K_VERSION_UDP << 24) |
00756 ( ED2K_VERSION_COMPRESSION << 20) |
00757 ( ED2K_VERSION_SECUREID << 16) |
00758 ( ED2K_VERSION_SOURCEEXCHANGE << 12) |
00759 ( nExtendedRequests << 8) |
00760 ( ED2K_VERSION_COMMENTS << 4) |
00761 ( FALSE << 3) |
00762 ( TRUE << 2) |
00763 ( FALSE << 1) |
00764 ( FALSE ) );
00765
00766 CEDTag( ED2K_CT_FEATUREVERSIONS, nVersion ).Write( pPacket );
00767
00768
00769 CEDTag( ED2K_CT_UDPPORTS, htons( Network.m_pHost.sin_port ) ).Write( pPacket );
00770
00771
00772
00773
00774
00775
00776
00777 if ( pServer != NULL )
00778 {
00779 pPacket->WriteLongLE( pServer->m_pHost.sin_addr.S_un.S_addr );
00780 pPacket->WriteShortLE( htons( pServer->m_pHost.sin_port ) );
00781 }
00782 else
00783 {
00784 pPacket->WriteLongLE( 0 );
00785 pPacket->WriteShortLE( 0 );
00786 }
00787
00788 Send( pPacket );
00789 }
00790
00791 BOOL CEDClient::OnHello(CEDPacket* pPacket)
00792 {
00793 if ( m_bLogin ) return TRUE;
00794
00795 if ( pPacket->GetRemaining() < sizeof(GUID) + 6 + 4 + 6 )
00796 {
00797 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_HANDSHAKE_FAIL, (LPCTSTR)m_sAddress );
00798 Close();
00799 return FALSE;
00800 }
00801
00802 GGUID pGUID;
00803 pPacket->Read( &pGUID, sizeof(GUID) );
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 m_bGUID = TRUE;
00818 m_pGUID = pGUID;
00819 m_nClientID = pPacket->ReadLongLE();
00820 m_pHost.sin_port = htons( pPacket->ReadShortLE() );
00821
00822 DWORD nCount = pPacket->ReadLongLE();
00823
00824 while ( nCount-- > 0 && pPacket->GetRemaining() > 0 )
00825 {
00826 CEDTag pTag;
00827 if ( ! pTag.Read( pPacket, ED2K_SERVER_TCP_UNICODE ) )
00828 {
00829 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_HANDSHAKE_FAIL, (LPCTSTR)m_sAddress );
00830 Close();
00831 return FALSE;
00832 }
00833 switch ( pTag.m_nKey )
00834 {
00835 case ED2K_CT_NAME:
00836 if ( pTag.m_nType == ED2K_TAG_STRING ) m_sNick = pTag.m_sValue;
00837 break;
00838 case ED2K_CT_PORT:
00839 if ( pTag.m_nType == ED2K_TAG_INT ) m_pHost.sin_port = htons( (WORD)pTag.m_nValue );
00840 break;
00841 case ED2K_CT_VERSION:
00842 if ( pTag.m_nType == ED2K_TAG_INT ) m_nVersion = pTag.m_nValue;
00843 break;
00844 case ED2K_CT_MODVERSION:
00845 break;
00846 case ED2K_CT_UDPPORTS:
00847 if ( pTag.m_nType == ED2K_TAG_INT ) m_nUDP = (WORD)(pTag.m_nValue & 0x0000FFFF);
00848 break;
00849 case ED2K_CT_FEATUREVERSIONS:
00850 if ( pTag.m_nType == ED2K_TAG_INT )
00851 {
00852 m_bEmule = TRUE;
00853 m_bEmAICH = (pTag.m_nValue >> 29) & 0x07;
00854 m_bEmUnicode = (pTag.m_nValue >> 28) & 0x01;
00855 m_bEmUDPVersion = (pTag.m_nValue >> 24) & 0x0F;
00856 m_bEmDeflate = (pTag.m_nValue >> 20) & 0x0F;
00857 m_bEmSecureID = (pTag.m_nValue >> 16) & 0x0F;
00858 m_bEmSources = (pTag.m_nValue >> 12) & 0x0F;
00859 m_bEmRequest = (pTag.m_nValue >> 8 ) & 0x0F;
00860 m_bEmComments = (pTag.m_nValue >> 4 ) & 0x0F;
00861 m_bEmPeerCache = (pTag.m_nValue >> 3 ) & 0x01;
00862 m_bEmBrowse =!(pTag.m_nValue >> 2 ) & 0x01;
00863 m_bEmMultiPacket= (pTag.m_nValue >> 1 ) & 0x01;
00864 m_bEmPreview = (pTag.m_nValue) & 0x01;
00865 }
00866 break;
00867 case ED2K_CT_SOFTWAREVERSION:
00868 if ( pTag.m_nType == ED2K_TAG_INT )
00869 {
00870 m_bEmule = TRUE;
00871 m_nSoftwareVersion = pTag.m_nValue & 0x00FFFFFF;
00872 m_nEmCompatible = pTag.m_nValue >> 24;
00873 }
00874 break;
00875 case ED2K_CT_UNKNOWN1:
00876 break;
00877 case ED2K_CT_UNKNOWN2:
00878 break;
00879 case ED2K_CT_MOREFEATUREVERSIONS:
00880
00881 break;
00882 case ED2K_CT_UNKNOWN3:
00883 break;
00884 default:
00885 if ( _tcsicmp( pTag.m_sKey, _T("pr") ) == 0 )
00886 {
00887
00888 }
00889 else
00890 {
00891 CString str;
00892 str.Format( _T("Unrecognised packet - IP: %s - opcode: 0x%x - in CEDClient::OnHello"),
00893 LPCTSTR( m_sAddress ), int( pTag.m_nKey ) );
00894 theApp.Message( MSG_DEBUG, LPCTSTR( str ) );
00895 }
00896 }
00897 }
00898
00899 if ( pPacket->GetRemaining() < 6 )
00900 {
00901 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_HANDSHAKE_FAIL, (LPCTSTR)m_sAddress );
00902 Close();
00903 return FALSE;
00904 }
00905
00906
00907 m_pServer.sin_addr.S_un.S_addr = pPacket->ReadLongLE();
00908 m_pServer.sin_port = htons( pPacket->ReadShortLE() );
00909
00910
00911 if ( Settings.eDonkey.LearnNewServersClient && ! Network.IsFirewalledAddress( &m_pServer.sin_addr ) )
00912 {
00913 HostCache.eDonkey.Add( &m_pServer.sin_addr, htons( m_pServer.sin_port ) );
00914 }
00915
00916
00917 if ( pPacket->GetRemaining() >= 4 )
00918 {
00919
00920 DWORD nValue = pPacket->ReadLongLE();
00921
00922
00923 if ( nValue == 0x4B444C4D ) m_nEmCompatible = 10;
00924 }
00925
00926
00927
00928 DeriveSoftwareVersion();
00929
00930
00931 if ( pPacket->m_nType == ED2K_C2C_HELLO )
00932 {
00933
00934 if ( ( m_bEmule ) && ( ! m_nSoftwareVersion ) )
00935 SendEmuleInfo( ED2K_C2C_EMULEINFO );
00936
00937
00938 SendHello( ED2K_C2C_HELLOANSWER );
00939 }
00940
00941 if ( m_bLogin )
00942 return TRUE;
00943 else
00944 return OnLoggedIn();
00945 }
00946
00948
00949
00950 void CEDClient::SendEmuleInfo(BYTE nType)
00951 {
00952 CEDPacket* pPacket = CEDPacket::New( nType, ED2K_PROTOCOL_EMULE );
00953
00954 pPacket->WriteByte( 0x40 );
00955 pPacket->WriteByte( 0x01 );
00956
00957
00958 pPacket->WriteLongLE( Settings.eDonkey.ExtendedRequest ? 7 : 6 );
00959
00960
00961 CEDTag( ED2K_ET_COMPATIBLECLIENT, ED2K_COMPATIBLECLIENT_ID ).Write( pPacket );
00962 CEDTag( ED2K_ET_COMPRESSION, ED2K_VERSION_COMPRESSION ).Write( pPacket );
00963 CEDTag( ED2K_ET_SOURCEEXCHANGE, ED2K_VERSION_SOURCEEXCHANGE ).Write( pPacket );
00964 CEDTag( ED2K_ET_UDPVER, ED2K_VERSION_UDP ).Write( pPacket );
00965 CEDTag( ED2K_ET_UDPPORT, htons( Network.m_pHost.sin_port ) ).Write( pPacket );
00966 CEDTag( ED2K_ET_COMMENTS, ED2K_VERSION_COMMENTS ).Write( pPacket );
00967 if ( Settings.eDonkey.ExtendedRequest ) CEDTag( ED2K_ET_EXTENDEDREQUEST, ED2K_VERSION_EXTENDEDREQUEST ).Write( pPacket );
00968 Send( pPacket );
00969 }
00970
00971 BOOL CEDClient::OnEmuleInfo(CEDPacket* pPacket)
00972 {
00973 if ( pPacket->GetRemaining() < 5 )
00974 {
00975 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_HANDSHAKE_FAIL, (LPCTSTR)m_sAddress );
00976 Close();
00977 return FALSE;
00978 }
00979
00980 m_nEmVersion = pPacket->ReadByte();
00981 BYTE nProtocol = pPacket->ReadByte();
00982
00983 if ( nProtocol != 1 ) return TRUE;
00984
00985
00986 if ( m_nEmVersion > 0x22 && m_nEmVersion < 0x25 ) m_bEmSources = 1;
00987 if ( m_nEmVersion == 0x24 ) m_bEmComments = 1;
00988
00989 m_nEmCompatible = ED2K_CLIENT_UNKNOWN;
00990
00991
00992 DWORD nCount = pPacket->ReadLongLE();
00993
00994 while ( nCount-- > 0 && pPacket->GetRemaining() > 0 )
00995 {
00996 CEDTag pTag;
00997
00998
00999 if ( ! pTag.Read( pPacket ) )
01000 {
01001 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_HANDSHAKE_FAIL, (LPCTSTR)m_sAddress );
01002 Close();
01003 return FALSE;
01004 }
01005
01006 switch ( pTag.m_nKey )
01007 {
01008 case ED2K_ET_COMPRESSION:
01009 if ( pTag.m_nType == ED2K_TAG_INT ) m_bEmDeflate = pTag.m_nValue;
01010 break;
01011 case ED2K_ET_UDPPORT:
01012 if ( pTag.m_nType == ED2K_TAG_INT ) m_nUDP = (WORD)pTag.m_nValue;
01013 break;
01014 case ED2K_ET_UDPVER:
01015 if ( pTag.m_nType == ED2K_TAG_INT ) m_bEmUDPVersion = (WORD)pTag.m_nValue;
01016 break;
01017 case ED2K_ET_SOURCEEXCHANGE:
01018 if ( pTag.m_nType == ED2K_TAG_INT ) m_bEmSources = pTag.m_nValue;
01019 break;
01020 case ED2K_ET_COMMENTS:
01021 if ( pTag.m_nType == ED2K_TAG_INT ) m_bEmComments = pTag.m_nValue;
01022 break;
01023 case ED2K_ET_EXTENDEDREQUEST:
01024 if ( pTag.m_nType == ED2K_TAG_INT ) m_bEmRequest = pTag.m_nValue;
01025 break;
01026 case ED2K_ET_COMPATIBLECLIENT:
01027 if ( pTag.m_nType == ED2K_TAG_INT ) m_nEmCompatible = pTag.m_nValue;
01028 break;
01029 case ED2K_ET_FEATURES:
01030 break;
01031 case ED2K_CT_MODVERSION:
01032 if ( m_nEmCompatible == ED2K_CLIENT_UNKNOWN )
01033 m_nEmCompatible = ED2K_CLIENT_MOD;
01034 break;
01035 default:
01036 CString str;
01037 str.Format( _T("Unrecognised packet - IP: %s - opcode: 0x%x - in CEDClient::OnEmuleInfo"),
01038 LPCTSTR( m_sAddress ), int( pTag.m_nKey ) );
01039 theApp.Message( MSG_DEBUG, LPCTSTR( str ) );
01040 }
01041 }
01042
01043 m_bEmule = TRUE;
01044
01045
01046 if ( pPacket->m_nType == ED2K_C2C_EMULEINFO ) SendEmuleInfo( ED2K_C2C_EMULEINFOANSWER );
01047
01048
01049 DeriveVersion();
01050
01051 return TRUE;
01052 }
01053
01055
01056
01057
01058 void CEDClient::DeriveSoftwareVersion()
01059 {
01060
01061 if ( m_nSoftwareVersion )
01062 {
01063
01064 m_bEmule = TRUE;
01065
01066
01067 switch ( m_nEmCompatible )
01068 {
01069 case 0:
01070 m_sUserAgent.Format( _T("eMule %i.%i%c"),
01071 ( ( m_nSoftwareVersion >> 17 ) & 0x7F ), ( ( m_nSoftwareVersion >> 10 ) & 0x7F ),
01072 ( ( m_nSoftwareVersion >> 7 ) & 0x07 ) + 'a' );
01073
01074
01075
01076
01077
01078
01079 break;
01080 case 1:
01081 m_sUserAgent.Format( _T("cDonkey %i.%i%c"),
01082 ( ( m_nSoftwareVersion >> 17 ) & 0x7F ), ( ( m_nSoftwareVersion >> 10 ) & 0x7F ),
01083 ( ( m_nSoftwareVersion >> 7 ) & 0x07 ) + 'a' );
01084 break;
01085 case 2:
01086 m_sUserAgent.Format( _T("xMule %i.%i%c"),
01087 ( ( m_nSoftwareVersion >> 17 ) & 0x7F ), ( ( m_nSoftwareVersion >> 10 ) & 0x7F ),
01088 ( ( m_nSoftwareVersion >> 7 ) & 0x07 ) + 'a' );
01089 break;
01090 case 3:
01091 m_sUserAgent.Format( _T("aMule %i.%i%c"),
01092 ( ( m_nSoftwareVersion >> 17 ) & 0x7F ), ( ( m_nSoftwareVersion >> 10 ) & 0x7F ),
01093 ( ( m_nSoftwareVersion >> 7 ) & 0x07 ) + 'a' );
01094 break;
01095 case 4:
01096
01097 m_sUserAgent.Format( _T("Shareaza %i.%i.%i.%i"),
01098 ( ( m_nSoftwareVersion >> 17 ) &0x7F ), ( ( m_nSoftwareVersion >> 10 ) &0x7F ),
01099 ( ( m_nSoftwareVersion >> 7 ) &0x07 ), ( ( m_nSoftwareVersion ) &0x7F ) );
01100
01101
01102 if ( m_pUpload ) m_pUpload->m_bClientExtended = TRUE;
01103 if ( m_pDownload && m_pDownload->m_pSource ) m_pDownload->m_pSource->m_bClientExtended = TRUE;
01104 break;
01105 case 5:
01106 m_sUserAgent.Format( _T("ePlus %i.%i%c"),
01107 ( ( m_nSoftwareVersion >> 17 ) & 0x7F ), ( ( m_nSoftwareVersion >> 10 ) & 0x7F ),
01108 ( ( m_nSoftwareVersion >> 7 ) & 0x07 ) + 'a' );
01109 break;
01110 case 10:
01111 m_sUserAgent.Format( _T("MlDonkey") );
01112 break;
01113 case 20:
01114 m_sUserAgent.Format( _T("Lphant %i.%i%c"),
01115 ( ( m_nSoftwareVersion >> 17 ) & 0x7F ), ( ( m_nSoftwareVersion >> 10 ) & 0x7F ),
01116 ( ( m_nSoftwareVersion >> 7 ) & 0x07 ) + 'a' );
01117 break;
01118 case 40:
01119
01120 m_sUserAgent.Format( _T("Shareaza %i.%i.%i.%i"),
01121 ( ( m_nSoftwareVersion >> 17 ) &0x7F ), ( ( m_nSoftwareVersion >> 10 ) &0x7F ),
01122 ( ( m_nSoftwareVersion >> 7 ) &0x07 ), ( ( m_nSoftwareVersion ) &0x7F ) );
01123
01124
01125 if ( m_pUpload ) m_pUpload->m_bClientExtended = TRUE;
01126 if ( m_pDownload && m_pDownload->m_pSource ) m_pDownload->m_pSource->m_bClientExtended = TRUE;
01127 break;
01128 default:
01129 m_sUserAgent.Format( _T("eMule/c(%i) %i.%i%c"), m_nEmCompatible,
01130 ( ( m_nSoftwareVersion >> 17 ) & 0x7F ), ( ( m_nSoftwareVersion >> 10 ) & 0x7F ),
01131 ( ( m_nSoftwareVersion >> 7 ) & 0x07 ) + 'a' );
01132 break;
01133 }
01134 }
01135 else
01136 {
01137 DeriveVersion();
01138 }
01139 }
01140
01141
01142 void CEDClient::DeriveVersion()
01143 {
01144 if ( m_nSoftwareVersion ) return;
01145
01146 if ( m_pGUID.n[5] == 13 && m_pGUID.n[14] == 110 )
01147 {
01148 m_bEmule = TRUE;
01149 m_sUserAgent.Format( _T("eMule v%i"), m_nVersion );
01150 }
01151 else if ( m_pGUID.n[5] == 14 && m_pGUID.n[14] == 111 )
01152 {
01153 m_bEmule = TRUE;
01154 m_sUserAgent.Format( _T("eMule v%i"), m_nVersion );
01155 }
01156 else if ( m_pGUID.n[5] == 'M' && m_pGUID.n[14] == 'L' )
01157 {
01158 m_sUserAgent.Format( _T("mlDonkey v%i"), m_nVersion );
01159 }
01160 else
01161 {
01162 if ( m_nVersion >= 1000 )
01163 m_sUserAgent.Format( _T("eDonkey v1.%i"), m_nVersion - 1000 );
01164 else
01165 m_sUserAgent.Format( _T("eDonkey v1.%i"), m_nVersion);
01166 }
01167
01168
01169 if ( m_bEmule && m_nEmVersion > 0 )
01170 {
01171 switch ( m_nEmCompatible )
01172 {
01173 case 0:
01174 m_sUserAgent.Format( _T("eMule v0.%i%i"), m_nEmVersion >> 4, m_nEmVersion & 15 );
01175 break;
01176 case 1:
01177 m_sUserAgent.Format( _T("cDonkey v%i.%i"), m_nEmVersion >> 4, m_nEmVersion & 15 );
01178 break;
01179 case 2:
01180 m_sUserAgent.Format( _T("xMule v0.%i%i"), m_nEmVersion >> 4, m_nEmVersion & 15 );
01181 break;
01182 case 3:
01183 m_sUserAgent.Format( _T("aMule v0.%i%i"), m_nEmVersion >> 4, m_nEmVersion & 15 );
01184 break;
01185 case 4:
01186 m_sUserAgent.Format( _T("Shareaza") );
01187 if ( m_pUpload ) m_pUpload->m_bClientExtended = TRUE;
01188 if ( m_pDownload && m_pDownload->m_pSource ) m_pDownload->m_pSource->m_bClientExtended = TRUE;
01189 break;
01190 case 10:
01191 m_sUserAgent.Format( _T("MlDonkey v0.%i%i"), m_nEmVersion >> 4, m_nEmVersion & 15 );
01192 break;
01193 case 20:
01194 m_sUserAgent.Format( _T("Lphant v0.%i%i"), m_nEmVersion >> 4, m_nEmVersion & 15 );
01195 break;
01196 case 40:
01197 m_sUserAgent.Format( _T("Shareaza") );
01198 if ( m_pUpload ) m_pUpload->m_bClientExtended = TRUE;
01199 if ( m_pDownload && m_pDownload->m_pSource ) m_pDownload->m_pSource->m_bClientExtended = TRUE;
01200 break;
01201 case ED2K_CLIENT_MOD:
01202 m_sUserAgent.Format( _T("eMule mod %i"), m_nEmVersion );
01203 break;
01204 case ED2K_CLIENT_UNKNOWN:
01205 if ( _tcsistr( m_sNick, _T("www.pruna.com") ) )
01206 m_sUserAgent.Format( _T("Pruna %i"), m_nEmVersion );
01207 else
01208 m_sUserAgent.Format( _T("Unidentified %i"), m_nEmVersion );
01209 break;
01210 default:
01211 m_sUserAgent.Format( _T("eMule/c (%i) v0.%i%i"), m_nEmCompatible, m_nEmVersion >> 4, m_nEmVersion & 15 );
01212 break;
01213 }
01214 }
01215 }
01216
01218
01219
01220 BOOL CEDClient::OnFileRequest(CEDPacket* pPacket)
01221 {
01222 int nRating;
01223 CString strComments;
01224
01225 if ( pPacket->GetRemaining() < sizeof(MD4) )
01226 {
01227 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
01228 return TRUE;
01229 }
01230
01231 CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILEREQANSWER );
01232
01233 pPacket->Read( &m_pUpMD4, sizeof(MD4) );
01234 pReply->Write( &m_pUpMD4, sizeof(MD4) );
01235
01236
01237
01238 if ( Security.IsDenied( &m_pHost.sin_addr ) )
01239 {
01240 pReply->m_nType = ED2K_C2C_FILENOTFOUND;
01241 Send( pReply );
01242 theApp.Message( MSG_ERROR, _T("ED2K upload to %s blocked by security rules."), m_sAddress);
01243 return TRUE;
01244 }
01245
01246 m_bUpMD4 = TRUE;
01247
01248 CSingleLock oLock( &Library.m_pSection,TRUE );
01249 CLibraryFile* pFile = LibraryMaps.LookupFileByED2K( &m_pUpMD4, TRUE, TRUE );
01250 if ( ( pFile ) && ( UploadQueues.CanUpload( PROTOCOL_ED2K, pFile, TRUE ) ) )
01251 {
01252
01253 pReply->WriteEDString( pFile->m_sName, m_bEmUnicode );
01254
01255 nRating = pFile->m_nRating;
01256 strComments = pFile->m_sComments;
01257 oLock.Unlock();
01258
01259
01260 Send( pReply );
01261
01262 SendCommentsPacket( nRating, strComments );
01263
01264
01265 return TRUE;
01266 }
01267 oLock.Unlock();
01268
01269 if ( CDownload* pDownload = Downloads.FindByED2K( &m_pUpMD4, TRUE ) )
01270 {
01271 pReply->WriteEDString( pDownload->m_sRemoteName, m_bEmUnicode );
01272 Send( pReply );
01273 return TRUE;
01274 }
01275
01276 pReply->m_nType = ED2K_C2C_FILENOTFOUND;
01277 Send( pReply );
01278
01279 theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress,
01280 (LPCTSTR)CED2K::HashToString( &m_pUpMD4, TRUE ) );
01281
01282 return TRUE;
01283 }
01284
01286
01287
01288 BOOL CEDClient::OnFileStatusRequest(CEDPacket* pPacket)
01289 {
01290 if ( pPacket->GetRemaining() < sizeof(MD4) )
01291 {
01292 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
01293 return TRUE;
01294 }
01295
01296 CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILESTATUS );
01297
01298 pPacket->Read( &m_pUpMD4, sizeof(MD4) );
01299 pReply->Write( &m_pUpMD4, sizeof(MD4) );
01300 m_bUpMD4 = TRUE;
01301
01302 CSingleLock oLock( &Library.m_pSection, TRUE );
01303 if ( CLibraryFile* pFile = LibraryMaps.LookupFileByED2K( &m_pUpMD4, TRUE, TRUE ) )
01304 {
01305 pReply->WriteShortLE( 0 );
01306 pReply->WriteByte( 0 );
01307
01308 m_nUpSize = pFile->GetSize();
01309 if ( ! CEDPacket::IsLowID( m_nClientID ) )
01310 pFile->AddAlternateSource( GetSourceURL() );
01311
01312 oLock.Unlock();
01313 Send( pReply );
01314 return TRUE;
01315 }
01316 oLock.Unlock();
01317 if ( CDownload* pDownload = Downloads.FindByED2K( &m_pUpMD4, TRUE ) )
01318 {
01319 WritePartStatus( pReply, pDownload );
01320 m_nUpSize = pDownload->m_nSize;
01321
01322 if ( ! pDownload->IsMoving() )
01323 pDownload->AddSourceED2K( m_nClientID, htons( m_pHost.sin_port ),
01324 m_pServer.sin_addr.S_un.S_addr, htons( m_pServer.sin_port ), &m_pGUID );
01325
01326 Send( pReply );
01327 return TRUE;
01328 }
01329
01330 m_bUpMD4 = FALSE;
01331
01332 pReply->m_nType = ED2K_C2C_FILENOTFOUND;
01333 Send( pReply );
01334
01335 theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress,
01336 (LPCTSTR)CED2K::HashToString( &m_pUpMD4, TRUE ) );
01337
01338 return TRUE;
01339 }
01340
01342
01343
01344 BOOL CEDClient::OnHashsetRequest(CEDPacket* pPacket)
01345 {
01346 if ( pPacket->GetRemaining() < sizeof(MD4) )
01347 {
01348 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
01349 return TRUE;
01350 }
01351
01352 MD4 pHash;
01353 pPacket->Read( &pHash, sizeof(MD4) );
01354
01355 CED2K* pHashset = NULL;
01356 BOOL bDelete = FALSE;
01357 CString strName;
01358
01359 CSingleLock oLock( &Library.m_pSection, TRUE );
01360 if ( CLibraryFile* pFile = LibraryMaps.LookupFileByED2K( &pHash, TRUE, TRUE ) )
01361 {
01362 strName = pFile->m_sName;
01363 pHashset = pFile->GetED2K();
01364 bDelete = TRUE;
01365 oLock.Unlock();
01366 }
01367 else
01368 {
01369 oLock.Unlock();
01370 if ( CDownload* pDownload = Downloads.FindByED2K( &pHash, TRUE ) )
01371 {
01372 if ( pHashset = pDownload->GetHashset() )
01373 {
01374 strName = pDownload->m_sRemoteName;
01375 bDelete = FALSE;
01376 }
01377 }
01378 }
01379
01380 if ( pHashset != NULL )
01381 {
01382 CEDPacket* pReply = CEDPacket::New( ED2K_C2C_HASHSETANSWER );
01383 pReply->Write( &pHash, sizeof(MD4) );
01384 int nBlocks = pHashset->GetBlockCount();
01385 if ( nBlocks <= 1 ) nBlocks = 0;
01386 pReply->WriteShortLE( (WORD)nBlocks );
01387 pReply->Write( pHashset->GetRawPtr(), sizeof(MD4) * nBlocks );
01388 if ( bDelete ) delete pHashset;
01389 Send( pReply );
01390
01391 theApp.Message( MSG_DEFAULT, IDS_ED2K_CLIENT_SENT_HASHSET,
01392 (LPCTSTR)strName, (LPCTSTR)m_sAddress );
01393 }
01394 else
01395 {
01396 CEDPacket* pReply = CEDPacket::New( ED2K_C2C_FILENOTFOUND );
01397 pReply->Write( &pHash, sizeof(MD4) );
01398 Send( pReply );
01399
01400 theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress,
01401 (LPCTSTR)CED2K::HashToString( &pHash, TRUE ) );
01402 }
01403
01404 return TRUE;
01405 }
01406
01408
01409
01410 BOOL CEDClient::OnQueueRequest(CEDPacket* pPacket)
01411 {
01412 if ( m_bUpMD4 == FALSE )
01413 {
01414
01415 return TRUE;
01416 }
01417
01418 if ( m_pUpload != NULL && m_pUpload->m_pED2K != m_pUpMD4 )
01419 DetachUpload();
01420
01421 if ( m_pUpload == NULL )
01422 m_pUpload = new CUploadTransferED2K( this );
01423
01424 m_pUpload->Request( &m_pUpMD4 );
01425
01426 return TRUE;
01427 }
01428
01430
01431
01432 BOOL CEDClient::OnMessage(CEDPacket* pPacket)
01433 {
01434 DWORD nMessageLength;
01435 CString sMessage;
01436
01437
01438 if ( pPacket->GetRemaining() < 3 )
01439 {
01440 theApp.Message( MSG_ERROR, _T("Empty message packet received from %s"), (LPCTSTR)m_sAddress );
01441 return TRUE;
01442 }
01443
01444
01445 nMessageLength = pPacket->ReadShortLE();
01446
01447
01448 if ( ( nMessageLength < 1 ) || ( nMessageLength > ED2K_MESSAGE_MAX ) || ( nMessageLength != pPacket->GetRemaining() ) )
01449 {
01450 theApp.Message( MSG_ERROR, _T("Invalid message packet received from %s"), (LPCTSTR)m_sAddress );
01451 return TRUE;
01452 }
01453
01454
01455 if ( m_bEmUnicode )
01456 sMessage = pPacket->ReadStringUTF8( nMessageLength );
01457 else
01458 sMessage = pPacket->ReadString( nMessageLength );
01459
01460
01461
01462 if ( MessageFilter.IsED2KSpam( sMessage ) )
01463 {
01464
01465 if ( m_pDownload == NULL ) Security.Ban( &m_pHost.sin_addr, banSession, FALSE );
01466
01467 return TRUE;
01468 }
01469 if ( MessageFilter.IsFiltered( sMessage ) ) return TRUE;
01470
01471
01472 if ( Settings.Community.ChatEnable && Settings.Community.ChatAllNetworks )
01473 {
01474
01475 ChatCore.OnED2KMessage( this, pPacket );
01476 }
01477 else
01478 {
01479
01480 theApp.Message( MSG_DEFAULT, _T("Message from %s: %s"), (LPCTSTR)m_sAddress, sMessage );
01481 }
01482 return TRUE;
01483 }
01484
01486
01487
01488 BOOL CEDClient::OnSourceRequest(CEDPacket* pPacket)
01489 {
01490 if ( pPacket->GetRemaining() < sizeof(MD4) )
01491 {
01492 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
01493 return TRUE;
01494 }
01495
01496 MD4 pHash;
01497 pPacket->Read( &pHash, sizeof(MD4) );
01498
01499 CEDPacket* pReply = CEDPacket::New( ED2K_C2C_ANSWERSOURCES, ED2K_PROTOCOL_EMULE );
01500 int nCount = 0;
01501
01502 if ( CDownload* pDownload = Downloads.FindByED2K( &pHash, TRUE ))
01503 {
01504 for ( CDownloadSource* pSource = pDownload->GetFirstSource() ; pSource ; pSource = pSource->m_pNext )
01505 {
01506 if ( pSource->m_nProtocol == PROTOCOL_ED2K && pSource->m_bReadContent )
01507 {
01508 pReply->WriteLongLE( pSource->m_pAddress.S_un.S_addr );
01509 pReply->WriteShortLE( pSource->m_nPort );
01510 pReply->WriteLongLE( pSource->m_pServerAddress.S_un.S_addr );
01511 pReply->WriteShortLE( (WORD)pSource->m_nServerPort );
01512 if ( m_bEmSources >= 2 ) pReply->Write( &pSource->m_pGUID, sizeof(GGUID) );
01513 nCount++;
01514 }
01515 }
01516 }
01517
01518 if ( pReply->m_nLength > 0 )
01519 {
01520 BYTE* pStart = pReply->WriteGetPointer( sizeof(MD4) + 2, 0 );
01521 CopyMemory( pStart, &pHash, sizeof(MD4) );
01522 pStart += sizeof(MD4);
01523 *(WORD*)pStart = nCount;
01524 Send( pReply, FALSE );
01525 }
01526
01527 pReply->Release();
01528
01529 return TRUE;
01530 }
01531
01533
01534
01535 BOOL CEDClient::OnSourceAnswer(CEDPacket* pPacket)
01536 {
01537 if ( Settings.Library.SourceMesh == FALSE ) return TRUE;
01538
01539 if ( pPacket->GetRemaining() < sizeof(MD4) + 2 )
01540 {
01541 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
01542 return TRUE;
01543 }
01544
01545 MD4 pHash;
01546 pPacket->Read( &pHash, sizeof(MD4) );
01547 int nCount = pPacket->ReadShortLE();
01548
01549 if ( pPacket->GetRemaining() < nCount * ( m_bEmSources >= 2 ? 12+16 : 12 ) )
01550 {
01551 theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
01552 return TRUE;
01553 }
01554
01555 if ( CDownload* pDownload = Downloads.FindByED2K( &pHash ))
01556 {
01557
01558 if ( pDownload->IsMoving() ) return TRUE;
01559
01560 while ( nCount-- > 0 )
01561 {
01562 GGUID pGUID;
01563
01564 DWORD nClientID = pPacket->ReadLongLE();
01565 WORD nClientPort = pPacket->ReadShortLE();
01566 DWORD nServerIP = pPacket->ReadLongLE();
01567 WORD nServerPort = pPacket->ReadShortLE();
01568
01569 if ( m_bEmSources >= 2 )
01570 {
01571 pPacket->Read( &pGUID, sizeof(GGUID) );
01572 pDownload->AddSourceED2K( nClientID, nClientPort, nServerIP, nServerPort, &pGUID );
01573 }
01574 else
01575 {
01576 pDownload->AddSourceED2K( nClientID, nClientPort, nServerIP, nServerPort );
01577 }
01578 }
01579 }
01580
01581 return TRUE;
01582 }
01583
01585
01586
01587 CString CEDClient::GetSourceURL()
01588 {
01589 ASSERT( m_bGUID );
01590 ASSERT( m_bUpMD4 );
01591
01592 CString str;
01593
01594 if ( CEDPacket::IsLowID( m_nClientID ) )
01595 {
01596 str.Format( _T("ed2kftp://%lu@%s:%i/%s/%I64i/"),
01597 m_nClientID,
01598 (LPCTSTR)CString( inet_ntoa( m_pHost.sin_addr ) ),
01599 htons( m_pHost.sin_port ),
01600 (LPCTSTR)CED2K::HashToString( &m_pUpMD4 ), m_nUpSize );
01601 }
01602 else
01603 {
01604 str.Format( _T("ed2kftp://%s:%lu/%s/%I64i/"),
01605 (LPCTSTR)CString( inet_ntoa( m_pHost.sin_addr ) ),
01606 htons( m_pHost.sin_port ),
01607 (LPCTSTR)CED2K::HashToString( &m_pUpMD4 ), m_nUpSize );
01608 }
01609
01610 return str;
01611 }
01612
01614
01615
01616 void CEDClient::WritePartStatus(CEDPacket* pPacket, CDownload* pDownload)
01617 {
01618 QWORD nParts = ( pDownload->m_nSize + ED2K_PART_SIZE - 1 ) / ED2K_PART_SIZE;
01619 pPacket->WriteShortLE( (WORD)nParts );
01620
01621 if ( pDownload->m_pHashsetBlock != NULL && pDownload->m_nHashsetBlock == nParts )
01622 {
01623 for ( QWORD nPart = 0 ; nPart < nParts ; )
01624 {
01625 BYTE nByte = 0;
01626
01627 for ( DWORD nBit = 0 ; nBit < 8 && nPart < nParts ; nBit++, nPart++ )
01628 {
01629 if ( pDownload->m_pHashsetBlock[ nPart ] == TS_TRUE )
01630 {
01631 nByte |= ( 1 << nBit );
01632 }
01633 }
01634
01635 pPacket->WriteByte( nByte );
01636 }
01637 }
01638 else
01639 {
01640 for ( QWORD nPart = 0 ; nPart < nParts ; )
01641 {
01642 BYTE nByte = 0;
01643
01644 for ( DWORD nBit = 0 ; nBit < 8 && nPart < nParts ; nBit++, nPart++ )
01645 {
01646 QWORD nOffset = nPart * ED2K_PART_SIZE;
01647 QWORD nLength = min( QWORD(ED2K_PART_SIZE), pDownload->m_nSize - nOffset );
01648
01649 if ( pDownload->IsRangeUseful( nOffset, nLength ) == FALSE )
01650 {
01651 nByte |= ( 1 << nBit );
01652 }
01653 }
01654
01655 pPacket->WriteByte( nByte );
01656 }
01657 }
01658 }
01659
01661
01662
01663 BOOL CEDClient::OnUdpReask(CEDPacket* pPacket)
01664 {
01665 if ( pPacket->GetRemaining() < sizeof(MD4) ) return FALSE;
01666 if ( m_bUpMD4 == FALSE || m_pUpload == NULL ) return FALSE;
01667
01668 MD4 pMD4;
01669 pPacket->Read( &pMD4, sizeof(MD4) );
01670 if ( pMD4 != m_pUpMD4 ) return FALSE;
01671
01672 return m_pUpload->OnReask();
01673 }
01674
01675 BOOL CEDClient::OnUdpReaskAck(CEDPacket* pPacket)
01676 {
01677 if ( pPacket->GetRemaining() < 2 ) return FALSE;
01678 if ( m_pDownload == NULL ) return FALSE;
01679
01680 int nRank = pPacket->ReadShortLE();
01681 m_pDownload->SetQueueRank( nRank );
01682
01683 return TRUE;
01684 }
01685
01686 BOOL CEDClient::OnUdpQueueFull(CEDPacket* pPacket)
01687 {
01688 if ( m_pDownload != NULL )
01689 {
01690 m_pDownload->m_pSource->m_tAttempt = GetTickCount() + Settings.eDonkey.ReAskTime * 1000;
01691 m_pDownload->Close( TS_UNKNOWN );
01692 }
01693
01694 return TRUE;
01695 }
01696
01697 BOOL CEDClient::OnUdpFileNotFound(CEDPacket* pPacket)
01698 {
01699 if ( m_pDownload != NULL ) m_pDownload->Close( TS_FALSE );
01700 return TRUE;
01701 }