1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
10 //
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
24 //
25 
26 #ifndef UPDOWNCLIENT_H
27 #define UPDOWNCLIENT_H
28 
29 #include "Constants.h"		// Needed for ESourceFrom
30 #include "GetTickCount.h"	// Needed for GetTickCount
31 #include "MD4Hash.h"
32 #include <common/StringFunctions.h>
33 #include <common/Macros.h>
34 #include "NetworkFunctions.h"
35 #include "OtherStructs.h"
36 #include "ClientCredits.h"	// Needed for EIdentState
37 #include <ec/cpp/ECID.h>	// Needed for CECID
38 #include "BitVector.h"		// Needed for BitVector
39 #include "ClientRef.h"		// Needed for debug defines
40 
41 #include <map>
42 
43 
44 class CPartFile;
45 class CClientTCPSocket;
46 class CPacket;
47 class CFriend;
48 class CKnownFile;
49 class CMemFile;
50 class CAICHHash;
51 
52 
53 enum EChatCaptchaState {
54 	CA_NONE				= 0,
55 	CA_CHALLENGESENT,
56 	CA_CAPTCHASOLVED,
57 	CA_ACCEPTING,
58 	CA_CAPTCHARECV,
59 	CA_SOLUTIONSENT
60 };
61 
62 enum ESecureIdentState {
63 	IS_UNAVAILABLE		= 0,
64 	IS_ALLREQUESTSSEND	= 0,
65 	IS_SIGNATURENEEDED	= 1,
66 	IS_KEYANDSIGNEEDED	= 2
67 };
68 
69 enum EInfoPacketState {
70 	IP_NONE			= 0,
71 	IP_EDONKEYPROTPACK	= 1,
72 	IP_EMULEPROTPACK	= 2,
73 	IP_BOTH			= 3
74 };
75 
76 enum EKadState {
77 	KS_NONE,
78 	KS_QUEUED_FWCHECK,
79 	KS_CONNECTING_FWCHECK,
80 	KS_CONNECTED_FWCHECK,
81 	KS_QUEUED_BUDDY,
82 	KS_INCOMING_BUDDY,
83 	KS_CONNECTING_BUDDY,
84 	KS_CONNECTED_BUDDY,
85 	KS_QUEUED_FWCHECK_UDP,
86 	KS_FWCHECK_UDP,
87 	KS_CONNECTING_FWCHECK_UDP
88 };
89 
90 //! Used to keep track of the state of the client
91 enum ClientState
92 {
93 	//! New is for clients that have just been created.
94 	CS_NEW = 0,
95 	//! Listed is for clients that are on the clientlist
96 	CS_LISTED,
97 	//! Dying signifies clients that have been queued for deletion
98 	CS_DYING
99 };
100 
101 // This is fixed on ed2k v1, but can be any number on ED2Kv2
102 #define STANDARD_BLOCKS_REQUEST 3
103 
104 class CUpDownClient : public CECID
105 {
106 	friend class CClientList;
107 	friend class CClientRef;
108 private:
109 	/**
110 	 * Please note that only the ClientList is allowed to delete the clients.
111 	 * To schedule a client for deletion, call the CClientList::AddToDeleteQueue
112 	 * funtion, which will safely remove dead clients once every second.
113 	 */
114 	~CUpDownClient();
115 
116 	/**
117 	 * Reference count which is increased whenever client is linked to a clientref.
118 	 * Clients are to be stored only by ClientRefs, CUpDownClient * are for temporary
119 	 * use only.
120 	 * Linking is done only by CClientRef which is friend, so methods are private.
121 	 */
122 	uint16 m_linked;
123 #ifdef DEBUG_ZOMBIE_CLIENTS
124 	bool	m_linkedDebug;
125 	std::multiset<wxString> m_linkedFrom;
Link(const wxString & from)126 	void	Link(const wxString& from)		{ m_linked++; m_linkedFrom.insert(from); }
127 	void	Unlink(const wxString& from);
GetLinkedFrom()128 	wxString GetLinkedFrom() {
129 		wxString ret;
130 		for (std::multiset<wxString>::iterator it = m_linkedFrom.begin(); it != m_linkedFrom.end(); ++it) {
131 			ret += *it + wxT(", ");
132 		}
133 		return ret;
134 	}
135 #else
Link()136 	void	Link()		{ m_linked++; }
137 	void	Unlink();
138 #endif
139 
140 public:
141 	//base
142 	CUpDownClient(CClientTCPSocket* sender = 0);
143 	CUpDownClient(uint16 in_port, uint32 in_userid, uint32 in_serverup, uint16 in_serverport,CPartFile* in_reqfile, bool ed2kID, bool checkfriend);
144 
145 	/**
146 	 * This function is to be called when the client object is to be deleted.
147 	 * It'll close the socket of the client and remove it from various lists
148 	 * that can own it.
149 	 *
150 	 * The client will really be deleted only after thelast reference to it
151 	 * is unlinked;
152 	 */
153 	void		Safe_Delete();
154 
155 	/**
156 	 * Specifies if the client has been queued for deletion.
157 	 *
158 	 * @return True if Safe_Delete has been called, false otherwise.
159 	 */
HasBeenDeleted()160 	bool		HasBeenDeleted()		{ return m_clientState == CS_DYING; }
161 
GetClientState()162 	ClientState	GetClientState()		{ return m_clientState; }
163 
164 	bool		Disconnected(const wxString& strReason, bool bFromSocket = false);
165 	bool		TryToConnect(bool bIgnoreMaxCon = false);
166 	bool		Connect();
167 	void		ConnectionEstablished();
GetUserName()168 	const wxString&	GetUserName() const		{ return m_Username; }
169 	//Only use this when you know the real IP or when your clearing it.
170 	void		SetIP( uint32 val );
GetIP()171 	uint32		GetIP() const			{ return m_dwUserIP; }
HasLowID()172 	bool		HasLowID() const		{ return IsLowID(m_nUserIDHybrid); }
GetFullIP()173 	wxString	GetFullIP() const		{ return Uint32toStringIP(m_FullUserIP); }
GetConnectIP()174 	uint32		GetConnectIP() const		{ return m_nConnectIP; }
GetUserIDHybrid()175 	uint32		GetUserIDHybrid() const		{ return m_nUserIDHybrid; }
176 	void		SetUserIDHybrid(uint32 val);
GetUserPort()177 	uint16_t	GetUserPort() const		{ return m_nUserPort; }
SetUserPort(uint16_t port)178 	void		SetUserPort(uint16_t port)	{ m_nUserPort = port; }
GetTransferredDown()179 	uint64		GetTransferredDown() const	{ return m_nTransferredDown; }
GetServerIP()180 	uint32		GetServerIP() const		{ return m_dwServerIP; }
SetServerIP(uint32 nIP)181 	void		SetServerIP(uint32 nIP)		{ m_dwServerIP = nIP; }
GetServerPort()182 	uint16		GetServerPort()	const		{ return m_nServerPort; }
SetServerPort(uint16 nPort)183 	void		SetServerPort(uint16 nPort)	{ m_nServerPort = nPort; }
GetUserHash()184 	const CMD4Hash&	GetUserHash() const		{ return m_UserHash; }
185 	void		SetUserHash(const CMD4Hash& userhash);
ValidateHash()186 	void		ValidateHash()			{ m_HasValidHash = !m_UserHash.IsEmpty(); }
HasValidHash()187 	bool		HasValidHash() const		{ return m_HasValidHash; }
GetVersion()188 	uint32		GetVersion() const		{ return m_nClientVersion;}
GetMuleVersion()189 	uint8		GetMuleVersion() const		{ return m_byEmuleVersion;}
ExtProtocolAvailable()190 	bool		ExtProtocolAvailable() const	{ return m_bEmuleProtocol;}
IsEmuleClient()191 	bool		IsEmuleClient()	const		{ return (m_byEmuleVersion > 0);}
192 	bool		IsBanned() const;
GetClientFilename()193 	const wxString&	GetClientFilename() const	{ return m_clientFilename; }
GetUDPPort()194 	uint16		GetUDPPort() const		{ return m_nUDPPort; }
SetUDPPort(uint16 nPort)195 	void		SetUDPPort(uint16 nPort)	{ m_nUDPPort = nPort; }
GetUDPVersion()196 	uint8		GetUDPVersion() const		{ return m_byUDPVer; }
GetExtendedRequestsVersion()197 	uint8		GetExtendedRequestsVersion() const { return m_byExtendedRequestsVer; }
IsFriend()198 	bool		IsFriend() const		{ return m_Friend != NULL; }
IsML()199 	bool		IsML() const			{ return m_bIsML; }
IsHybrid()200 	bool		IsHybrid() const		{ return m_bIsHybrid; }
GetCompatibleClient()201 	uint32		GetCompatibleClient() const	{ return m_byCompatibleClient; }
202 
203 	void		ClearDownloadBlockRequests();
204 	void		RequestSharedFileList();
205 	void		ProcessSharedFileList(const uint8_t* pachPacket, uint32 nSize, wxString& pszDirectory);
206 	void		SendSharedDirectories();
207 	void		SendSharedFilesOfDirectory(const wxString& strReqDir);
208 
209 	wxString	GetUploadFileInfo();
210 
SetUserName(const wxString & NewName)211 	void		SetUserName(const wxString& NewName) { m_Username = NewName; }
212 
GetClientSoft()213 	uint8		GetClientSoft() const		{ return m_clientSoft; }
214 	void		ReGetClientSoft();
215 	bool		ProcessHelloAnswer(const uint8_t* pachPacket, uint32 nSize);
216 	bool		ProcessHelloPacket(const uint8_t* pachPacket, uint32 nSize);
217 	void		SendHelloAnswer();
218 	bool		SendHelloPacket();
219 	void		SendMuleInfoPacket(bool bAnswer, bool OSInfo = false);
220 	bool		ProcessMuleInfoPacket(const uint8_t* pachPacket, uint32 nSize);
221 	void		ProcessMuleCommentPacket(const uint8_t* pachPacket, uint32 nSize);
222 	bool		Compare(const CUpDownClient* tocomp, bool bIgnoreUserhash = false) const;
SetLastSrcReqTime()223 	void		SetLastSrcReqTime()		{ m_dwLastSourceRequest = ::GetTickCount(); }
SetLastSrcAnswerTime()224 	void		SetLastSrcAnswerTime()		{ m_dwLastSourceAnswer = ::GetTickCount(); }
SetLastAskedForSources()225 	void		SetLastAskedForSources()	{ m_dwLastAskedForSources = ::GetTickCount(); }
GetLastSrcReqTime()226 	uint32		GetLastSrcReqTime() const	{ return m_dwLastSourceRequest; }
GetLastSrcAnswerTime()227 	uint32		GetLastSrcAnswerTime() const	{ return m_dwLastSourceAnswer; }
GetLastAskedForSources()228 	uint32		GetLastAskedForSources() const	{ return m_dwLastAskedForSources; }
GetFriendSlot()229 	bool		GetFriendSlot() const		{ return m_bFriendSlot; }
SetFriendSlot(bool bNV)230 	void		SetFriendSlot(bool bNV)		{ m_bFriendSlot = bNV; }
231 	void		SetCommentDirty(bool bDirty = true)	{ m_bCommentDirty = bDirty; }
GetSourceExchange1Version()232 	uint8		GetSourceExchange1Version() const	{ return m_bySourceExchange1Ver; }
SupportsSourceExchange2()233 	bool		SupportsSourceExchange2() const		{ return m_fSupportsSourceEx2; }
234 
235 	bool		SafeSendPacket(CPacket* packet);
236 
237 	void		ProcessRequestPartsPacket(const uint8_t* pachPacket, uint32 nSize, bool largeblocks);
238 	void		ProcessRequestPartsPacketv2(const CMemFile& data);
239 
240 	void		SendPublicKeyPacket();
241 	void		SendSignaturePacket();
242 	void		ProcessPublicKeyPacket(const uint8_t* pachPacket, uint32 nSize);
243 	void		ProcessSignaturePacket(const uint8_t* pachPacket, uint32 nSize);
244 	uint8		GetSecureIdentState();
245 
246 	void		SendSecIdentStatePacket();
247 	void		ProcessSecIdentStatePacket(const uint8_t* pachPacket, uint32 nSize);
248 
GetInfoPacketsReceived()249 	uint8		GetInfoPacketsReceived() const	{ return m_byInfopacketsReceived; }
250 	void		InfoPacketsReceived();
251 
252 	//upload
GetUploadState()253 	uint8		GetUploadState() const		{ return m_nUploadState; }
254 	void		SetUploadState(uint8 news);
GetTransferredUp()255 	uint64		GetTransferredUp() const	{ return m_nTransferredUp; }
GetSessionUp()256 	uint64		GetSessionUp() const		{ return m_nTransferredUp - m_nCurSessionUp; }
257 	void		ResetSessionUp();
GetUploadDatarate()258 	uint32		GetUploadDatarate() const	{ return m_nUpDatarate; }
259 
260 	//uint32		GetWaitTime() const		{ return m_dwUploadTime - GetWaitStartTime(); }
GetUpStartTimeDelay()261 	uint32		GetUpStartTimeDelay() const	{ return ::GetTickCount() - m_dwUploadTime; }
262 	uint32		GetWaitStartTime() const;
263 
IsDownloading()264 	bool		IsDownloading()	const		{ return (m_nUploadState == US_UPLOADING); }
265 
GetScore()266 	uint32		GetScore() const	{ return m_score; }
CalculateScore()267 	uint32		CalculateScore()	{ m_score = CalculateScoreInternal(); return m_score; }
ClearScore()268 	void		ClearScore()		{ m_score = 0; }
GetUploadQueueWaitingPosition()269 	uint16		GetUploadQueueWaitingPosition() const	{ return m_waitingPosition; }
SetUploadQueueWaitingPosition(uint16 pos)270 	void		SetUploadQueueWaitingPosition(uint16 pos)	{ m_waitingPosition = pos; }
271 	uint8		GetObfuscationStatus() const;
272 	uint16		GetNextRequestedPart() const;
273 
274 	void		AddReqBlock(Requested_Block_Struct* reqblock);
275 	void		CreateNextBlockPackage();
SetUpStartTime()276 	void		SetUpStartTime()		{ m_dwUploadTime = ::GetTickCount(); }
277 	void		SetWaitStartTime();
278 	void		ClearWaitStartTime();
279 	void		SendHashsetPacket(const CMD4Hash& forfileid);
SupportMultiPacket()280 	bool		SupportMultiPacket() const	{ return m_bMultiPacket; }
SupportExtMultiPacket()281 	bool		SupportExtMultiPacket() const	{ return m_fExtMultiPacket; }
282 
283 	void		SetUploadFileID(CKnownFile *newreqfile);
284 
285 	/**
286 	 *Gets the file actually on upload
287 	 *
288 	 */
GetUploadFile()289 	const CKnownFile* GetUploadFile() const		{ return m_uploadingfile; }
290 
291 	void		SendOutOfPartReqsAndAddToWaitingQueue();
292 	void		ProcessExtendedInfo(const CMemFile *data, CKnownFile *tempreqfile);
293 	void		ProcessFileInfo(const CMemFile* data, const CPartFile* file);
294 	void		ProcessFileStatus(bool bUdpPacket, const CMemFile* data, const CPartFile* file);
295 
GetUploadFileID()296 	const CMD4Hash&	GetUploadFileID() const		{ return m_requpfileid; }
297 	void		SetUploadFileID(const CMD4Hash& new_id);
ClearUploadFileID()298 	void		ClearUploadFileID()		{ m_requpfileid.Clear(); m_uploadingfile = NULL;}
299 	uint32		SendBlockData();
300 	void		ClearUploadBlockRequests();
301 	void		SendRankingInfo();
302 	void		SendCommentInfo(CKnownFile *file);
303 	bool		IsDifferentPartBlock() const;
304 	void		UnBan();
305 	void		Ban();
306 	bool		m_bAddNextConnect;      // VQB Fix for LowID slots only on connection
GetAskedCount()307 	uint32		GetAskedCount() const		{ return m_cAsked; }
AddAskedCount()308 	void		AddAskedCount()			{ m_cAsked++; }
ClearAskedCount()309 	void		ClearAskedCount()		{ m_cAsked = 1; }	// 1, because it's cleared *after* the first request...
310 	void		FlushSendBlocks();	// call this when you stop upload,
311 						// or the socket might be not able to send
SetLastUpRequest()312 	void		SetLastUpRequest()		{ m_dwLastUpRequest = ::GetTickCount(); }
GetLastUpRequest()313 	uint32		GetLastUpRequest() const	{ return m_dwLastUpRequest; }
GetUpPartCount()314 	size_t		GetUpPartCount() const		{ return m_upPartStatus.size(); }
315 
316 
317 	//download
318 	void		SetRequestFile(CPartFile* reqfile);
GetRequestFile()319 	CPartFile*	GetRequestFile() const		{ return m_reqfile; }
320 
GetDownloadState()321 	uint8		GetDownloadState() const	{ return m_nDownloadState; }
322 	void		SetDownloadState(uint8 byNewState);
GetLastAskedTime()323 	uint32		GetLastAskedTime() const	{ return m_dwLastAskedTime; }
ResetLastAskedTime()324 	void		ResetLastAskedTime()		{ m_dwLastAskedTime = 0; }
325 
IsPartAvailable(uint16 iPart)326 	bool		IsPartAvailable(uint16 iPart) const
327 					{ return ( iPart < m_downPartStatus.size() ) ? m_downPartStatus.get(iPart) : 0; }
IsUpPartAvailable(uint16 iPart)328 	bool		IsUpPartAvailable(uint16 iPart) const
329 					{ return ( iPart < m_upPartStatus.size() ) ? m_upPartStatus.get(iPart) : 0;}
330 
GetPartStatus()331 	const BitVector& GetPartStatus() const		{ return m_downPartStatus; }
GetUpPartStatus()332 	const BitVector& GetUpPartStatus() const	{ return m_upPartStatus; }
GetKBpsDown()333 	float		GetKBpsDown() const				{ return kBpsDown; }
334 	float		CalculateKBpsDown();
GetRemoteQueueRank()335 	uint16		GetRemoteQueueRank() const	{ return m_nRemoteQueueRank; }
GetOldRemoteQueueRank()336 	uint16		GetOldRemoteQueueRank() const	{ return m_nOldRemoteQueueRank; }
SetRemoteQueueFull(bool flag)337 	void		SetRemoteQueueFull(bool flag)	{ m_bRemoteQueueFull = flag; }
IsRemoteQueueFull()338 	bool		IsRemoteQueueFull() const	{ return m_bRemoteQueueFull; }
339 	void		SetRemoteQueueRank(uint16 nr);
340 	bool		AskForDownload();
341 	void		SendStartupLoadReq();
342 	void		SendFileRequest();
343 	void		ProcessHashSet(const uint8_t* packet, uint32 size);
344 	bool		AddRequestForAnotherFile(CPartFile* file);
345 	bool		DeleteFileRequest(CPartFile* file);
346 	void		DeleteAllFileRequests();
347 	void		SendBlockRequests();
348 	void		ProcessBlockPacket(const uint8_t* packet, uint32 size, bool packed, bool largeblocks);
349 	uint16		GetAvailablePartCount() const;
350 
351 	bool		SwapToAnotherFile(bool bIgnoreNoNeeded, bool ignoreSuspensions, bool bRemoveCompletely, CPartFile* toFile = NULL);
352 	void		UDPReaskACK(uint16 nNewQR);
353 	void		UDPReaskFNF();
354 	void		UDPReaskForDownload();
355 	bool		IsSourceRequestAllowed();
GetUpCompleteSourcesCount()356 	uint16		GetUpCompleteSourcesCount() const	{ return m_nUpCompleteSourcesCount; }
SetUpCompleteSourcesCount(uint16 n)357 	void		SetUpCompleteSourcesCount(uint16 n)	{ m_nUpCompleteSourcesCount = n; }
358 
359 	//chat
GetChatState()360 	uint8		GetChatState()			{ return m_byChatstate; }
SetChatState(uint8 nNewS)361 	void		SetChatState(uint8 nNewS)	{ m_byChatstate = nNewS; }
GetChatCaptchaState()362 	EChatCaptchaState GetChatCaptchaState() const	{ return (EChatCaptchaState)m_nChatCaptchaState; }
363 	void		ProcessCaptchaRequest(CMemFile* data);
364 	void		ProcessCaptchaReqRes(uint8 nStatus);
365 	void		ProcessChatMessage(wxString message);
366 	// message filtering
GetMessagesReceived()367 	uint8		GetMessagesReceived() const	{ return m_cMessagesReceived; }
IncMessagesReceived()368 	void		IncMessagesReceived()		{ m_cMessagesReceived < 255 ? ++m_cMessagesReceived : 255; }
GetMessagesSent()369 	uint8		GetMessagesSent() const		{ return m_cMessagesSent; }
IncMessagesSent()370 	void		IncMessagesSent()		{ m_cMessagesSent < 255 ? ++m_cMessagesSent : 255; }
IsSpammer()371 	bool		IsSpammer() const		{ return m_fIsSpammer; }
372 	void		SetSpammer(bool bVal);
373 	bool		IsMessageFiltered(const wxString& message);
374 
375 	//File Comment
GetFileComment()376 	const wxString&	GetFileComment() const		{ return m_strComment; }
GetFileRating()377 	uint8		GetFileRating() const		{ return m_iRating; }
378 
GetSoftStr()379 	const wxString&	GetSoftStr() const		{ return m_clientSoftString; }
GetSoftVerStr()380 	const wxString&	GetSoftVerStr() const		{ return m_clientVerString; }
381 	const wxString GetServerName() const;
382 
GetKadPort()383 	uint16		GetKadPort() const		{ return m_nKadPort; }
SetKadPort(uint16 nPort)384 	void		SetKadPort(uint16 nPort)	{ m_nKadPort = nPort; }
385 
386 	// Kry - AICH import
387 	void		SetReqFileAICHHash(CAICHHash* val);
GetReqFileAICHHash()388 	CAICHHash*	GetReqFileAICHHash() const	{return m_pReqFileAICHHash;}
IsSupportingAICH()389 	bool		IsSupportingAICH() const	{return m_fSupportsAICH & 0x01;}
390 	void		SendAICHRequest(CPartFile* pForFile, uint16 nPart);
IsAICHReqPending()391 	bool		IsAICHReqPending() const	{return m_fAICHRequested; }
392 	void		ProcessAICHAnswer(const uint8_t* packet, uint32 size);
393 	void		ProcessAICHRequest(const uint8_t* packet, uint32 size);
394 	void		ProcessAICHFileHash(CMemFile* data, const CPartFile* file);
395 
396 	EUtf8Str	GetUnicodeSupport() const;
397 
398 	// Barry - Process zip file as it arrives, don't need to wait until end of block
399 	int		unzip(Pending_Block_Struct *block, uint8_t *zipped, uint32 lenZipped, uint8_t **unzipped, uint32 *lenUnzipped, int iRecursion = 0);
400 	void		UpdateDisplayedInfo(bool force = false);
GetFileListRequested()401 	int		GetFileListRequested() const	{ return m_iFileListRequested; }
SetFileListRequested(int iFileListRequested)402 	void		SetFileListRequested(int iFileListRequested) { m_iFileListRequested = iFileListRequested; }
403 
404 	void		ResetFileStatusInfo();
405 
406 	bool		CheckHandshakeFinished() const;
407 
GetSentCancelTransfer()408 	bool		GetSentCancelTransfer() const	{ return m_fSentCancelTransfer; }
SetSentCancelTransfer(bool bVal)409 	void		SetSentCancelTransfer(bool bVal)	{ m_fSentCancelTransfer = bVal; }
410 
411 	DEBUG_ONLY( wxString	GetClientFullInfo(); )
412 	wxString	GetClientShortInfo();
413 
GetClientOSInfo()414 	const wxString& GetClientOSInfo() const		{ return m_sClientOSInfo; }
415 
416 	void		ProcessPublicIPAnswer(const uint8_t* pbyData, uint32 uSize);
417 	void		SendPublicIPRequest();
418 
419 	/**
420 	 * Sets the current socket of the client.
421 	 *
422 	 * @param socket The pointer to the new socket, can be NULL.
423 	 *
424 	 * Please note that this function DOES NOT delete the old socket.
425 	 */
426 	void		SetSocket(CClientTCPSocket* socket);
427 
428 	/**
429 	 * Function for accessing the socket owned by a client.
430 	 *
431 	 * @return The pointer (can be NULL) to the socket used by this client.
432 	 *
433 	 * Please note that the socket object is quite volatile and can be removed
434 	 * from one function call to the next, therefore, you should normally use
435 	 * the safer functions below, which all check if the socket is valid before
436 	 * deferring it.
437 	 */
GetSocket()438 	CClientTCPSocket* GetSocket() const		{ return m_socket; }
439 
440 	/**
441 	 * Safe function for checking if the socket is connected.
442 	 *
443 	 * @return True if the socket exists and is connected, false otherwise.
444 	 */
445 	bool		IsConnected() const;
446 
447 	/**
448 	 * Safe function for sending packets.
449 	 *
450 	 * @return True if the socket exists and the packet was sent, false otherwise.
451 	 */
452 	bool		SendPacket(CPacket* packet, bool delpacket = true, bool controlpacket = true);
453 
454 	/**
455 	 * Safe function for setting the download limit of the socket.
456 	 *
457 	 * @return Current download speed of the client.
458 	 */
459 	float		SetDownloadLimit(uint32 reducedownload);
460 
461 	/**
462 	 * Sends a message to a client
463 	 *
464 	 * @return True if sent, false if connecting
465 	 */
466 	bool		SendChatMessage(const wxString& message);
467 
HasBlocks()468 	bool		HasBlocks() const		{ return !m_BlockRequests_queue.empty(); }
469 
470 	/* Source comes from? */
GetSourceFrom()471 	ESourceFrom		GetSourceFrom() const	{ return m_nSourceFrom; }
SetSourceFrom(ESourceFrom val)472 	void			SetSourceFrom(ESourceFrom val)	{ m_nSourceFrom = val; }
473 
474 	/* Kad buddy support */
475 	// ID
GetBuddyID()476 	const uint8_t*	GetBuddyID() const	{ return m_achBuddyID; }
477 	void		SetBuddyID(const uint8_t* m_achTempBuddyID);
HasValidBuddyID()478 	bool		HasValidBuddyID() const		{ return m_bBuddyIDValid; }
479 	/* IP */
SetBuddyIP(uint32 val)480 	void		SetBuddyIP( uint32 val )	{ m_nBuddyIP = val; }
GetBuddyIP()481 	uint32		GetBuddyIP() const		{ return m_nBuddyIP; }
482 	/* Port */
SetBuddyPort(uint16 val)483 	void		SetBuddyPort( uint16 val )	{ m_nBuddyPort = val; }
GetBuddyPort()484 	uint16		GetBuddyPort() const		{ return m_nBuddyPort; }
485 
486 	//KadIPCheck
SendBuddyPingPong()487 	bool		SendBuddyPingPong()		{ return m_dwLastBuddyPingPongTime < ::GetTickCount(); }
AllowIncomeingBuddyPingPong()488 	bool		AllowIncomeingBuddyPingPong()	{ return m_dwLastBuddyPingPongTime < (::GetTickCount()-(3*60*1000)); }
SetLastBuddyPingPongTime()489 	void		SetLastBuddyPingPongTime()	{ m_dwLastBuddyPingPongTime = (::GetTickCount()+(10*60*1000)); }
GetKadState()490 	EKadState	GetKadState() const		{ return m_nKadState; }
SetKadState(EKadState nNewS)491 	void		SetKadState(EKadState nNewS)	{ m_nKadState = nNewS; }
GetKadVersion()492 	uint8		GetKadVersion()			{ return m_byKadVersion; }
493 	void		ProcessFirewallCheckUDPRequest(CMemFile *data);
494 	// Kad added by me
495 	bool		SendBuddyPing();
496 
497 	/* Returns the client hash type (SO_EMULE, mldonkey, etc) */
498 	int		GetHashType() const;
499 
500 	/**
501 	 * Checks that a client isn't aggressively re-asking for files.
502 	 *
503 	 * Call this when a file is requested. If the time since the last request is
504 	 * less than MIN_REQUESTTIME, 3 is added to the m_Aggressiveness variable.
505 	 * If the time since the last request is >= MIN_REQUESTTIME, the variable is
506 	 * decremented by 1. The client is banned if the variable reaches 10 or above.
507 	 *
508 	 * To check if a client is aggressive use the IsClientAggressive() function.
509 	 *
510 	 * Currently this function is called when the following packets are received:
511 	 *  - OP_STARTUPLOADREQ
512 	 *  - OP_REASKFILEPING
513 	 */
514 	void		CheckForAggressive();
515 
GetClientModString()516 	const wxString&	GetClientModString() const	{ return m_strModVersion; }
517 
GetClientVerString()518 	const wxString&	GetClientVerString() const	{ return m_fullClientVerString; }
519 
GetVersionString()520 	const wxString&	GetVersionString() const	{ return m_clientVersionString; }
521 
522 	void		UpdateStats();
523 
524 	/* Returns a pointer to the credits, only for hash purposes */
GetCreditsHash()525 	void*		GetCreditsHash() const { return (void*)credits; }
526 
GetLastDownloadingPart()527 	uint16		GetLastDownloadingPart() const { return m_lastDownloadingPart; }
528 
GetOSInfoSupport()529 	bool		GetOSInfoSupport() const { return m_fOsInfoSupport; }
530 
GetVBTTags()531 	bool		GetVBTTags() const { return m_fValueBasedTypeTags; }
532 
GetLastPartAsked()533 	uint16		GetLastPartAsked() const { return m_lastPartAsked; }
534 
SetLastPartAsked(uint16 nPart)535 	void		SetLastPartAsked(uint16 nPart) { m_lastPartAsked = nPart; }
536 
GetFriend()537 	CFriend*	GetFriend() const { return m_Friend; }
538 
SetFriend(CFriend * newfriend)539 	void		SetFriend(CFriend* newfriend) { m_Friend = newfriend; }
540 
541 	bool		IsIdentified() const;
542 
543 	bool		IsBadGuy() const;
544 
545 	bool		SUIFailed() const;
546 
547 	bool		SUINeeded() const;
548 
549 	bool		SUINotSupported() const;
550 
551 	uint64		GetDownloadedTotal() const;
552 
553 	uint64		GetUploadedTotal() const;
554 
555 	double		GetScoreRatio() const;
556 
GetCreationTime()557 	uint32		GetCreationTime() const { return m_nCreationTime; }
558 
SupportsLargeFiles()559 	bool		SupportsLargeFiles() const { return m_fSupportsLargeFiles; }
560 
GetCurrentIdentState()561 	EIdentState	GetCurrentIdentState() const { return credits ? credits->GetCurrentIdentState(GetIP()) : IS_NOTAVAILABLE; }
562 
563 #ifdef __DEBUG__
564 	/* Kry - Debug. See connection_reason definition comment below */
SetConnectionReason(const wxString & reason)565 	void		SetConnectionReason(const wxString& reason) { connection_reason = reason; }
566 #endif
567 
568 	// Encryption / Obfuscation / ConnectOptions
SupportsCryptLayer()569 	bool		SupportsCryptLayer() const			{ return m_fSupportsCryptLayer; }
RequestsCryptLayer()570 	bool		RequestsCryptLayer() const			{ return SupportsCryptLayer() && m_fRequestsCryptLayer; }
RequiresCryptLayer()571 	bool		RequiresCryptLayer() const			{ return RequestsCryptLayer() && m_fRequiresCryptLayer; }
SupportsDirectUDPCallback()572 	bool		SupportsDirectUDPCallback() const		{ return m_fDirectUDPCallback != 0 && HasValidHash() && GetKadPort() != 0; }
GetDirectCallbackTimeout()573 	uint32_t	GetDirectCallbackTimeout() const		{ return m_dwDirectCallbackTimeout; }
HasObfuscatedConnectionBeenEstablished()574 	bool		HasObfuscatedConnectionBeenEstablished() const	{ return m_hasbeenobfuscatinglately; }
575 
SetCryptLayerSupport(bool bVal)576 	void		SetCryptLayerSupport(bool bVal)			{ m_fSupportsCryptLayer = bVal ? 1 : 0; }
SetCryptLayerRequest(bool bVal)577 	void		SetCryptLayerRequest(bool bVal)			{ m_fRequestsCryptLayer = bVal ? 1 : 0; }
SetCryptLayerRequires(bool bVal)578 	void		SetCryptLayerRequires(bool bVal)		{ m_fRequiresCryptLayer = bVal ? 1 : 0; }
SetDirectUDPCallbackSupport(bool bVal)579 	void		SetDirectUDPCallbackSupport(bool bVal)		{ m_fDirectUDPCallback = bVal ? 1 : 0; }
580 	void		SetConnectOptions(uint8_t options, bool encryption = true, bool callback = true); // shortcut, sets crypt, callback, etc from the tagvalue we receive
581 	bool		ShouldReceiveCryptUDPPackets() const;
582 
HasDisabledSharedFiles()583 	bool		HasDisabledSharedFiles() const { return m_fNoViewSharedFiles; }
584 
585 private:
586 
587 	CClientCredits	*credits;
588 	CFriend		*m_Friend;
589 
590 	uint64		m_nTransferredUp;
591 	sint64		m_nCurQueueSessionPayloadUp;
592 	sint64		m_addedPayloadQueueSession;
593 
594 	struct TransferredData {
595 		uint32	datalen;
596 		uint32	timestamp;
597 	};
598 
599 	//////////////////////////////////////////////////////////
600 	// Upload data rate computation
601 	//
602 	uint32		m_nUpDatarate;
603 	uint32		m_nSumForAvgUpDataRate;
604 	std::list<TransferredData> m_AvarageUDR_list;
605 
606 
607 	/**
608 	 * This struct is used to keep track of CPartFiles which this source shares.
609 	 */
610 	struct A4AFStamp {
611 		//! Signifies if this sources has needed parts for this file.
612 		bool NeededParts;
613 		//! This is set when we wish to avoid swapping to this file for a while.
614 		uint32 timestamp;
615 	};
616 
617 	//! I typedef in the name of readability!
618 	typedef std::map<CPartFile*, A4AFStamp> A4AFList;
619 	//! This list contains all PartFiles which this client can be used as a source for.
620 	A4AFList m_A4AF_list;
621 
622 	/**
623 	 * Helper function used by SwapToAnotherFile().
624 	 *
625 	 * @param it The iterator of the PartFile to be examined.
626 	 * @param ignorenoneeded Do not check for the status NoNeededParts when checking the file.
627 	 * @param ignoresuspended Do not check the timestamp when checking the file.
628 	 * @return True if the file is a viable target, false otherwise.
629 	 *
630 	 * This function is used to perform checks to see if we should consider
631 	 * this file a viable target for A4AF swapping. Unless ignoresuspended is
632 	 * true, it will examine the timestamp of the file and reset it if needed.
633 	 */
634 	bool		IsValidSwapTarget( A4AFList::iterator it, bool ignorenoneeded = false, bool ignoresuspended = false );
635 
636 	CPartFile*	m_reqfile;
637 
638 	// base
639 	void		Init();
640 	bool		ProcessHelloTypePacket(const CMemFile& data);
641 	void		SendHelloTypePacket(CMemFile* data);
642 	void		SendFirewallCheckUDPRequest();
643 	void		ClearHelloProperties(); // eMule 0.42
644 
645 	uint32		m_dwUserIP;
646 	uint32		m_nConnectIP;		// holds the supposed IP or (after we had a connection) the real IP
647 	uint32		m_dwServerIP;
648 	uint32		m_nUserIDHybrid;
649 	uint16_t	m_nUserPort;
650 	int16		m_nServerPort;
651 	uint32		m_nClientVersion;
652 	uint32		m_cSendblock;
653 	uint8		m_byEmuleVersion;
654 	uint8		m_byDataCompVer;
655 	bool		m_bEmuleProtocol;
656 	wxString	m_Username;
657 	uint32		m_FullUserIP;
658 	CMD4Hash	m_UserHash;
659 	bool		m_HasValidHash;
660 	uint16		m_nUDPPort;
661 	uint8		m_byUDPVer;
662 	uint8		m_bySourceExchange1Ver;
663 	uint8		m_byAcceptCommentVer;
664 	uint8		m_byExtendedRequestsVer;
665 	uint8		m_clientSoft;
666 	uint32		m_dwLastSourceRequest;
667 	uint32		m_dwLastSourceAnswer;
668 	uint32		m_dwLastAskedForSources;
669 	int		m_iFileListRequested;
670 	bool		m_bFriendSlot;
671 	bool		m_bCommentDirty;
672 	bool		m_bIsHybrid;
673 	bool		m_bIsML;
674 	bool		m_bSupportsPreview;
675 	bool		m_bUnicodeSupport;
676 	uint16		m_nKadPort;
677 	bool		m_bMultiPacket;
678 	ClientState	m_clientState;
679 	CClientTCPSocket*	m_socket;
680 	bool		m_fNeedOurPublicIP; // we requested our IP from this client
681 
682 	// Kry - Secure User Ident import
683 	ESecureIdentState	m_SecureIdentState;
684 	uint8		m_byInfopacketsReceived;		// have we received the edonkeyprot and emuleprot packet already (see InfoPacketsReceived() )
685 	uint32		m_dwLastSignatureIP;
686 	uint8		m_bySupportSecIdent;
687 
688 	uint32		m_byCompatibleClient;
689 	std::list<CPacket*>	m_WaitingPackets_list;
690 	uint32		m_lastRefreshedDLDisplay;
691 
692 	//upload
693 	void CreateStandardPackets(const unsigned char* data,uint32 togo, Requested_Block_Struct* currentblock);
694 	void CreatePackedPackets(const unsigned char* data,uint32 togo, Requested_Block_Struct* currentblock);
695 	uint32 CalculateScoreInternal();
696 
697 	uint8		m_nUploadState;
698 	uint32		m_dwUploadTime;
699 	uint32		m_cAsked;
700 	uint32		m_dwLastUpRequest;
701 	uint32		m_nCurSessionUp;
702 	uint16		m_nUpPartCount;
703 	CMD4Hash	m_requpfileid;
704 	uint16		m_nUpCompleteSourcesCount;
705 	uint32		m_score;
706 	uint16		m_waitingPosition;
707 
708 	//! This vector contains the avilability of parts for the file that the user
709 	//! is requesting. When changing it, be sure to call CKnownFile::UpdatePartsFrequency
710 	//! so that the files know the actual availability of parts.
711 	BitVector	m_upPartStatus;
712 	uint16		m_lastPartAsked;
713 	wxString	m_strModVersion;
714 
715 	std::list<Requested_Block_Struct*>	m_BlockRequests_queue;
716 	std::list<Requested_Block_Struct*>	m_DoneBlocks_list;
717 
718 	//download
719 	bool		m_bRemoteQueueFull;
720 	uint8		m_nDownloadState;
721 	uint16		m_nPartCount;
722 	uint32		m_dwLastAskedTime;
723 	wxString	m_clientFilename;
724 	uint64		m_nTransferredDown;
725 	uint16		m_lastDownloadingPart;   // last Part that was downloading
726 	uint16		m_cShowDR;
727 	uint32		m_dwLastBlockReceived;
728 	uint16		m_nRemoteQueueRank;
729 	uint16		m_nOldRemoteQueueRank;
730 	bool		m_bCompleteSource;
731 	bool		m_bReaskPending;
732 	bool		m_bUDPPending;
733 	bool		m_bHashsetRequested;
734 
735 	std::list<Pending_Block_Struct*>	m_PendingBlocks_list;
736 	std::list<Requested_Block_Struct*>	m_DownloadBlocks_list;
737 
738 	// download speed calculation
739 	float		kBpsDown;
740 	uint32		msReceivedPrev;
741 	uint32		bytesReceivedCycle;
742 	// chat
743 	wxString	m_strComment;
744 	uint8		m_byChatstate;
745 	uint8		m_nChatCaptchaState;
746 	uint8		m_cCaptchasSent;
747 	int8		m_iRating;
748 	uint8		m_cMessagesReceived;		// count of chatmessages he sent to me
749 	uint8		m_cMessagesSent;			// count of chatmessages I sent to him
750 	wxString	m_strCaptchaChallenge;
751 	wxString	m_strCaptchaPendingMsg;
752 
753 	unsigned int
754 		m_fHashsetRequesting : 1, // we have sent a hashset request to this client
755 		m_fNoViewSharedFiles : 1, // client has disabled the 'View Shared Files' feature,
756 					  // if this flag is not set, we just know that we don't know
757 					  // for sure if it is enabled
758 		m_fSupportsPreview   : 1,
759 		m_fIsSpammer	     : 1,
760 		m_fSentCancelTransfer: 1, // we have sent an OP_CANCELTRANSFER in the current connection
761 		m_fSharedDirectories : 1, // client supports OP_ASKSHAREDIRS opcodes
762 		m_fSupportsAICH      : 3,
763 		m_fAICHRequested     : 1,
764 		m_fSupportsLargeFiles: 1,
765 		m_fSentOutOfPartReqs : 1,
766 		m_fExtMultiPacket    : 1,
767 		m_fRequestsCryptLayer: 1,
768 		m_fSupportsCryptLayer: 1,
769 		m_fRequiresCryptLayer: 1,
770 		m_fSupportsSourceEx2 : 1,
771 		m_fSupportsCaptcha   : 1,
772 		m_fDirectUDPCallback : 1;
773 
774 	unsigned int
775 		m_fOsInfoSupport : 1,
776 		m_fValueBasedTypeTags : 1;
777 
778 	/* Razor 1a - Modif by MikaelB */
779 
780 	bool		m_bHelloAnswerPending;
781 
782 	//! This vector contains the avilability of parts for the file we requested
783 	//! from this user. When changing it, be sure to call CPartFile::UpdatePartsFrequency
784 	//! so that the files know the actual availability of parts.
785 	BitVector	m_downPartStatus;
786 
787 	CAICHHash*	m_pReqFileAICHHash;
788 
789 	ESourceFrom	m_nSourceFrom;
790 
791 	/* Kad Stuff */
792 	uint8_t		m_achBuddyID[16];
793 	bool		m_bBuddyIDValid;
794 	uint32		m_nBuddyIP;
795 	uint16		m_nBuddyPort;
796 
797 	EKadState	m_nKadState;
798 
799 	uint8		m_byKadVersion;
800 	uint32		m_dwLastBuddyPingPongTime;
801 	uint32_t	m_dwDirectCallbackTimeout;
802 
803 	//! This keeps track of aggressive requests for files.
804 	uint16		m_Aggressiveness;
805 	//! This tracks the time of the last time since a file was requested
806 	uint32		m_LastFileRequest;
807 
808 	bool		m_OSInfo_sent;
809 
810 	wxString	m_clientSoftString;	/* software name */
811 	wxString	m_clientVerString;	/* version + optional mod name */
812 	wxString	m_clientVersionString;	/* version string */
813 	wxString	m_fullClientVerString;	/* full info string */
814 	wxString	m_sClientOSInfo;
815 	wxString	m_pendingMessage;
816 
817 	int		SecIdentSupRec;
818 
819 	CKnownFile*	m_uploadingfile;
820 
821 	uint8		m_MaxBlockRequests;
822 
823 	// needed for stats
824 	uint32		m_lastClientSoft;
825 	uint32		m_lastClientVersion;
826 	wxString	m_lastOSInfo;
827 
828 	/* For buddies timeout */
829 	uint32		m_nCreationTime;
830 
831 	/* Calculation of last average speed */
832 	uint32		m_lastaverage;
833 	uint32		m_last_block_start;
834 
835 	/* Save the encryption status for display when disconnected */
836 	bool		m_hasbeenobfuscatinglately;
837 
838 	/* Kry - Debug thing. Clients created just to check their data
839 	   have this string set to the reason we want to check them.
840 	   Obviously, once checked, we disconnect them. Take that, sucker.
841 	   This debug code is just for me I'm afraid. */
842 #ifdef __DEBUG__
843 	wxString	connection_reason;
844 #endif
845 };
846 
847 
848 #define	MAKE_CLIENT_VERSION(mjr, min, upd) \
849 	((uint32)(mjr)*100U*10U*100U + (uint32)(min)*100U*10U + (uint32)(upd)*100U)
850 
851 
852 #endif // UPDOWNCLIENT_H
853 // File_checked_for_headers
854