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