2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net )
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
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.
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.
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
29 #include "DeadSourceList.h" // Needed for CDeadSourceList
35 class CClientTCPSocket
;
51 #define BAN_CLEANUP_TIME 1200000 // 20 min
55 * This class takes care of managing existing clients.
57 * This class tracks a number of attributes related to existing and deleted
58 * clients. Among other things, it keeps track of existing, banned, dead and
59 * dying clients, as well as offers support for matching new client-instances
60 * against already exist clients to avoid duplicates.
77 * Adds a client to the global list of clients.
79 * @param toadd The new client.
81 void AddClient( CUpDownClient
* toadd
);
84 * Schedules a client for deletion.
86 * @param client The client to be deleted.
88 * Call this function whenever a client is to be deleted, rather than
89 * directly deleting the client. If the client is on the global client-
90 * list, then it will be scheduled for deletion, otherwise it will be
91 * deleted immediatly. Please check CUpDownClient::Safe_Delete for the
92 * proper way to do this.
94 void AddToDeleteQueue( CUpDownClient
* client
);
98 * Updates the recorded IP of the specified client.
100 * @param client The client to have its entry updated.
101 * @param newIP The new IP adress of the client.
103 * This function is to be called before the client actually changes its
104 * IP-address, and will update the old entry with the new value. There
105 * will only be added an entry if the new IP isn't zero.
107 void UpdateClientIP( CUpDownClient
* client
, uint32 newIP
);
110 * Updates the recorded ID of the specified client.
112 * @param client The client to have its entry updated.
113 * @param newID The new ID of the client.
115 * This function is to be called before the client actually changes its
116 * ID, and will update the old entry with the new value. Unlike the other
117 * two functions, this function will always ensure that there is an entry
118 * for the client, regardless of the value of newID.
120 void UpdateClientID( CUpDownClient
* client
, uint32 newID
);
123 * Updates the recorded hash of the specified client.
125 * @param client The client to have its entry updated.
126 * @param newHash The new user-hash.
128 * This function is to be called before the client actually changes its
129 * user-hash, and will update the old entry with the new value. There will
130 * only be added an entry if the new hash is valid.
132 void UpdateClientHash( CUpDownClient
* client
, const CMD4Hash
& newHash
);
136 * Returns the number of listed clients.
138 uint32
GetClientCount() const;
142 * Deletes all tracked clients.
148 * Replaces a new client-instance with the an already existing client, if one such exist.
150 * @param client A pointer to the pointer of the new instance.
151 * @param sender The socket assosiated with the new instance.
153 * Call this function when a new client-instance has been created. This function will then
154 * compare it against all existing clients and see if we already have an instance matching
155 * the new one. If that is the case, it will delete the new instance and set the pointer to
158 bool AttachToAlreadyKnown( CUpDownClient
** client
, CClientTCPSocket
* sender
);
162 * Finds a client with the specified ip and port.
164 * @param clientip The IP of the client to find.
165 * @param port The port used by the client.
167 CUpDownClient
* FindClientByIP( uint32 clientip
, uint16 port
);
170 //! The list-type used to store clients IPs and other information
171 typedef std::map
<uint32
, uint32
> ClientMap
;
175 * Adds a client to the list of tracked clients.
177 * @param toadd The client to track.
179 * This function is used to keep track of clients after they
180 * have been deleted and makes it possible to spot port or hash
183 void AddTrackClient(CUpDownClient
* toadd
);
186 * Returns the number of tracked client.
188 * @param dwIP The IP-adress which of the clients.
189 * @return The number of clients tracked at the specifed IP.
191 uint16
GetClientsFromIP(uint32 dwIP
);
194 * Checks if a client has changed its user-hash.
196 * @param dwIP The IP of the client.
197 * @param nPort The port of the client.
198 * @param pNewHash The userhash assosiated with the client.
201 bool ComparePriorUserhash( uint32 dwIP
, uint16 nPort
, void* pNewHash
);
205 * Bans an IP address for 2 hours.
207 * @param dwIP The IP from which all clients will be banned.
209 void AddBannedClient(uint32 dwIP
);
212 * Checks if a client has been banned.
214 * @param dwIP The IP to check.
215 * @return True if the IP is banned, false otherwise.
217 bool IsBannedClient(uint32 dwIP
);
220 * Unbans an IP address, if it has been banned.
222 * @param dwIP The IP address to unban.
224 void RemoveBannedClient(uint32 dwIP
);
230 * This function takes care of cleaning the various lists and deleting
231 * pending clients on the deletion-queue.
237 * Deletes clients previously queued for deletion
239 * This function takes care of deleting pending clients on the
242 void ProcessDeleteQueue();
246 * This function removes all clients filtered by the current IPFilter.
248 * Call this function after changing the current IPFiler list, to ensure
249 * that no client-connections to illegal IPs exist. These would otherwise
250 * be allowed to exist, bypassing the IPFilter.
255 //! The type of the list used to store client-pointers for a couple of tasks.
256 typedef std::deque
<CUpDownClient
*> SourceList
;
260 * Returns a list of clients with the specified user-hash.
262 * @param hash The userhash to search for.
264 * This function will return a list of clients with the specified userhash,
265 * provided that the hash is a valid non-empty userhash. Empty hashes will
266 * simply result in nothing being found.
268 SourceList
GetClientsByHash( const CMD4Hash
& hash
);
271 * Returns a list of clients with the specified IP.
273 * @param ip The IP-address to search for.
275 * This function will return a list of clients with the specified IP,
276 * provided that the IP is a non-zero value. A value of zero will not
277 * result in any results.
279 SourceList
GetClientsByIP( unsigned long ip
);
282 //! The type of the lists used to store IPs and IDs.
283 typedef std::multimap
<uint32
, CUpDownClient
*> IDMap
;
284 //! The pairs of the IP/ID list.
285 typedef std::pair
<uint32
, CUpDownClient
*> IDMapPair
;
289 * Returns a list of all clients.
291 * @return The complete list of clients.
293 const IDMap
& GetClientList();
297 * Adds a source to the list of dead sources.
299 * @param client The source to be recorded as dead.
301 void AddDeadSource(const CUpDownClient
* client
);
304 * Checks if a source is recorded as being dead.
306 * @param client The client to evaluate.
307 * @return True if dead, false otherwise.
309 * Sources that are dead are not to be considered valid
310 * sources and should not be added to partfiles.
312 bool IsDeadSource(const CUpDownClient
* client
);
315 * Sends a message to a client, identified by a GUI_ID
319 bool SendMessage(uint64 client_id
, const wxString
& message
);
322 * Stops a chat session with a client.
325 void SetChatState(uint64 client_id
, uint8 state
);
327 uint8
GetBuddyStatus() const {return m_nBuddyStatus
;}
328 // This must be used on CreateKadSourceLink and if we ever add the columns
329 // on shared files control.
330 CUpDownClient
* GetBuddy() const { return m_pBuddy
; }
331 bool RequestTCP(Kademlia::CContact
* contact
, uint8_t connectOptions
);
332 void RequestBuddy(Kademlia::CContact
* contact
, uint8_t connectOptions
);
333 bool IncomingBuddy(Kademlia::CContact
* contact
, Kademlia::CUInt128
* buddyID
);
334 void RemoveFromKadList(CUpDownClient
* torem
);
335 void AddToKadList(CUpDownClient
* toadd
);
336 bool DoRequestFirewallCheckUDP(const Kademlia::CContact
& contact
);
338 void AddKadFirewallRequest(uint32 ip
);
339 bool IsKadFirewallCheckIP(uint32 ip
) const;
341 // Direct Callback list
342 void AddDirectCallbackClient(CUpDownClient
*toAdd
);
343 void RemoveDirectCallback(CUpDownClient
*toRemove
) { m_currentDirectCallbacks
.remove(toRemove
); }
344 void AddTrackCallbackRequests(uint32_t ip
);
345 bool AllowCallbackRequest(uint32_t ip
) const;
349 * Avoids unwanted clients to be forever in the client list
351 void CleanUpClientList();
353 void ProcessDirectCallbackList();
357 * Helperfunction which finds a client matching the specified client.
359 * @param client The client to search for.
360 * @return The matching client or NULL.
362 * This functions searches through the list of clients and finds the first match
363 * using the same checks as CUpDownClient::Compare, but without the overhead.
365 CUpDownClient
* FindMatchingClient( CUpDownClient
* client
);
369 * Check if we already know this IP.
371 * This function is used to determine if the given IP address
374 * @param ip The IP address to check.
376 bool IsIPAlreadyKnown(uint32_t ip
);
380 * Helperfunction which removes the client from the IP-list.
382 void RemoveIPFromList( CUpDownClient
* client
);
384 * Helperfunction which removes the client from the ID-list.
386 bool RemoveIDFromList( CUpDownClient
* client
);
388 * Helperfunction which removes the client from the hash-list.
390 void RemoveHashFromList( CUpDownClient
* client
);
393 //! The type of the list used to store user-hashes.
394 typedef std::multimap
<CMD4Hash
, CUpDownClient
*> HashMap
;
395 //! The pairs of the Hash-list.
396 typedef std::pair
<CMD4Hash
, CUpDownClient
*> HashMapPair
;
399 //! The map of clients with valid hashes
402 //! The map of clients with valid IPs
405 //! The full lists of clients
408 //! This is the lists of clients that should be deleted
409 SourceList m_delete_queue
;
411 bool m_delete_queue_closed
;
414 //! This is the map of banned clients.
415 ClientMap m_bannedList
;
416 //! This variable is used to keep track of the last time the banned-list was pruned.
417 uint32 m_dwLastBannCleanUp
;
419 //! This is the map of tracked clients.
420 std::map
<uint32
, CDeletedClient
*> m_trackedClientsList
;
421 //! This keeps track of the last time the tracked-list was pruned.
422 uint32 m_dwLastTrackedCleanUp
;
424 //! This keeps track of the last time the client-list was pruned.
425 uint32 m_dwLastClientCleanUp
;
427 //! List of unusable sources.
428 CDeadSourceList m_deadSources
;
431 std::set
<CUpDownClient
*> m_KadSources
;
432 CUpDownClient
* m_pBuddy
;
433 uint8 m_nBuddyStatus
;
439 typedef std::list
<IpAndTicks
> IpAndTicksList
;
440 IpAndTicksList m_firewallCheckRequests
;
442 typedef std::list
<CUpDownClient
*> DirectCallbackList
;
443 DirectCallbackList m_currentDirectCallbacks
;
444 IpAndTicksList m_directCallbackRequests
;
448 // File_checked_for_headers