1 //								-*- C++ -*-
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2008-2011 Dévai Tamás ( gonosztopi@amule.org )
5 // Copyright (c) 2008-2011 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
7 //
8 // Any parts of this program derived from the xMule, lMule or eMule project,
9 // or contributed by third-party developers are copyrighted by their
10 // respective authors.
11 //
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
25 //
26 
27 #ifndef KADEMLIA_KADEMLIA_UDPFIREWALLTESTER_H
28 #define KADEMLIA_KADEMLIA_UDPFIREWALLTESTER_H
29 
30 #include "Kademlia.h"
31 #include "../routing/Contact.h"
32 #include <list>
33 
34 namespace Kademlia
35 {
36 
37 class CUInt128;
38 class CKadUDPKey;
39 
40 struct UsedClient_Struct {
41 	CContact	contact;
42 	bool		answered;
43 };
44 
45 #define UDP_FIREWALLTEST_CLIENTSTOASK	2	// more clients increase the chance of a false positive, while less the chance of a false negative
46 
47 class CUDPFirewallTester
48 {
49       public:
50 	static bool	IsFirewalledUDP(bool lastStateIfTesting); // Are we UDP firewalled - if unknown open is assumed unless onlyVerified == true
51 	static void	SetUDPFWCheckResult(bool succeeded, bool testCancelled, uint32_t fromIP, uint16_t incomingPort);
52 	static void	ReCheckFirewallUDP(bool setUnverified);
IsFWCheckUDPRunning()53 	static bool	IsFWCheckUDPRunning() throw()		{ return m_fwChecksFinishedUDP < UDP_FIREWALLTEST_CLIENTSTOASK && !CKademlia::IsRunningInLANMode(); }
IsVerified()54 	static bool	IsVerified() throw()			{ return m_isFWVerifiedUDP || CKademlia::IsRunningInLANMode(); }
55 
AddPossibleTestContact(const CUInt128 & clientID,uint32_t ip,uint16_t port,uint16_t tport,const CUInt128 & target,uint8_t version,const CKadUDPKey & udpKey,bool ipVerified)56 	static void	AddPossibleTestContact(const CUInt128& clientID, uint32_t ip, uint16_t port, uint16_t tport, const CUInt128& target, uint8_t version, const CKadUDPKey& udpKey, bool ipVerified)
57 	{
58 		if (!IsFWCheckUDPRunning()) {
59 			return;
60 		}
61 		// add the possible contact to our list - no checks in advance
62 		m_possibleTestClients.push_front(CContact(clientID, ip, port, tport, version, udpKey, ipVerified, target));
63 		QueryNextClient();
64 	}
65 
66 	static void	Reset(); // when stopping Kad
67 	static void	Connected();
68 	static void	QueryNextClient(); // try the next available client for the firewallcheck
69 
70       private:
71 	// are we in search for testclients
GetUDPCheckClientsNeeded()72 	static bool	GetUDPCheckClientsNeeded() throw()	{ return (m_fwChecksRunningUDP + m_fwChecksFinishedUDP) < UDP_FIREWALLTEST_CLIENTSTOASK; }
73 	static bool	m_firewalledUDP;
74 	static bool	m_firewalledLastStateUDP;
75 	static bool	m_isFWVerifiedUDP;
76 	static bool	m_nodeSearchStarted;
77 	static bool	m_timedOut;
78 	static uint8_t	m_fwChecksRunningUDP;
79 	static uint8_t	m_fwChecksFinishedUDP;
80 	static uint32_t	m_testStart;
81 	static uint32_t	m_lastSucceededTime;
82 	typedef std::list<CContact> PossibleClientList;
83 	typedef std::list<UsedClient_Struct> UsedClientList;
84 	static PossibleClientList m_possibleTestClients;
85 	static UsedClientList	m_usedTestClients;
86 };
87 
88 } // namespace Kademlia
89 
90 #endif /* KADEMLIA_KADEMLIA_UDPFIREWALLTESTER */
91