2 // This file is part of the aMule Project.
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 )
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
26 #include "ClientCredits.h" // Interface declarations
30 #include "GetTickCount.h" // Needed for GetTickCount
31 #include "Logger.h" // Needed for Add(Debug)LogLine
33 CreditStruct::CreditStruct()
40 memset(abySecureIdent
, 0, MAXPUBKEYSIZE
);
44 CClientCredits::CClientCredits(CreditStruct
* in_credits
)
46 m_pCredits
= in_credits
;
48 m_dwUnSecureWaitTime
= 0;
49 m_dwSecureWaitTime
= 0;
54 CClientCredits::CClientCredits(const CMD4Hash
& key
)
56 m_pCredits
= new CreditStruct();
57 m_pCredits
->key
= key
;
60 m_dwUnSecureWaitTime
= ::GetTickCount();
61 m_dwSecureWaitTime
= ::GetTickCount();
66 CClientCredits::~CClientCredits()
72 void CClientCredits::AddDownloaded(uint32 bytes
, uint32 dwForIP
, bool cryptoavail
)
74 switch (GetCurrentIdentState(dwForIP
)) {
87 m_pCredits
->downloaded
+= bytes
;
91 void CClientCredits::AddUploaded(uint32 bytes
, uint32 dwForIP
, bool cryptoavail
)
93 switch (GetCurrentIdentState(dwForIP
)) {
101 case IS_NOTAVAILABLE
:
106 m_pCredits
->uploaded
+= bytes
;
110 uint64
CClientCredits::GetUploadedTotal() const
112 return m_pCredits
->uploaded
;
116 uint64
CClientCredits::GetDownloadedTotal() const
118 return m_pCredits
->downloaded
;
122 float CClientCredits::GetScoreRatio(uint32 dwForIP
, bool cryptoavail
)
124 // check the client ident status
125 switch (GetCurrentIdentState(dwForIP
)) {
130 // bad guy - no credits for you
134 case IS_NOTAVAILABLE
:
139 if (GetDownloadedTotal() < 1000000) {
144 if (!GetUploadedTotal()) {
147 result
= (GetDownloadedTotal() * 2.0f
) / GetUploadedTotal();
150 float result2
= sqrt((GetDownloadedTotal() / 1048576.0) + 2.0f
);
151 if (result
> result2
) {
157 } else if (result
> 10.0f
) {
165 void CClientCredits::SetLastSeen()
167 m_pCredits
->nLastSeen
= time(NULL
);
171 void CClientCredits::InitalizeIdent()
173 if (m_pCredits
->nKeySize
== 0 ){
174 memset(m_abyPublicKey
,0,80); // for debugging
176 m_identState
= IS_NOTAVAILABLE
;
179 m_nPublicKeyLen
= m_pCredits
->nKeySize
;
180 memcpy(m_abyPublicKey
, m_pCredits
->abySecureIdent
, m_nPublicKeyLen
);
181 m_identState
= IS_IDNEEDED
;
183 m_dwCryptRndChallengeFor
= 0;
184 m_dwCryptRndChallengeFrom
= 0;
189 void CClientCredits::Verified(uint32 dwForIP
)
191 m_dwIdentIP
= dwForIP
;
192 // client was verified, copy the keyto store him if not done already
193 if (m_pCredits
->nKeySize
== 0){
194 m_pCredits
->nKeySize
= m_nPublicKeyLen
;
195 memcpy(m_pCredits
->abySecureIdent
, m_abyPublicKey
, m_nPublicKeyLen
);
196 if (GetDownloadedTotal() > 0){
197 // for security reason, we have to delete all prior credits here
198 // in order to save this client, set 1 byte
199 m_pCredits
->downloaded
= 1;
200 m_pCredits
->uploaded
= 1;
201 AddDebugLogLineN( logCredits
, wxT("Credits deleted due to new SecureIdent") );
204 m_identState
= IS_IDENTIFIED
;
208 bool CClientCredits::SetSecureIdent(const byte
* pachIdent
, uint8 nIdentLen
)
209 { // verified Public key cannot change, use only if there is not public key yet
210 if (MAXPUBKEYSIZE
< nIdentLen
|| m_pCredits
->nKeySize
!= 0 ) {
213 memcpy(m_abyPublicKey
,pachIdent
, nIdentLen
);
214 m_nPublicKeyLen
= nIdentLen
;
215 m_identState
= IS_IDNEEDED
;
220 EIdentState
CClientCredits::GetCurrentIdentState(uint32 dwForIP
) const
222 if (m_identState
!= IS_IDENTIFIED
)
225 if (dwForIP
== m_dwIdentIP
)
226 return IS_IDENTIFIED
;
229 // mod note: clients which just reconnected after an IP change and have to ident yet will also have this state for 1-2 seconds
230 // so don't try to spam such clients with "bad guy" messages (besides: spam messages are always bad)
235 uint32
CClientCredits::GetSecureWaitStartTime(uint32 dwForIP
)
237 if (m_dwUnSecureWaitTime
== 0 || m_dwSecureWaitTime
== 0)
238 SetSecWaitStartTime(dwForIP
);
240 if (m_pCredits
->nKeySize
!= 0){ // this client is a SecureHash Client
241 if (GetCurrentIdentState(dwForIP
) == IS_IDENTIFIED
){ // good boy
242 return m_dwSecureWaitTime
;
244 else{ // not so good boy
245 if (dwForIP
== m_dwWaitTimeIP
){
246 return m_dwUnSecureWaitTime
;
249 // this can also happen if the client has not identified himself yet, but will do later - so maybe he is not a bad boy :) .
251 m_dwUnSecureWaitTime
= ::GetTickCount();
252 m_dwWaitTimeIP
= dwForIP
;
253 return m_dwUnSecureWaitTime
;
257 else{ // not a SecureHash Client - handle it like before for now (no security checks)
258 return m_dwUnSecureWaitTime
;
263 void CClientCredits::SetSecWaitStartTime(uint32 dwForIP
)
265 m_dwUnSecureWaitTime
= ::GetTickCount()-1;
266 m_dwSecureWaitTime
= ::GetTickCount()-1;
267 m_dwWaitTimeIP
= dwForIP
;
271 void CClientCredits::ClearWaitStartTime()
273 m_dwUnSecureWaitTime
= 0;
274 m_dwSecureWaitTime
= 0;
277 // File_checked_for_headers