Upstream tarball 20080603
[amule.git] / src / ClientCredits.cpp
blob6605429e2de1d0ee662744a41da4d29edc562b8d
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002 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.
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.
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
26 #include "ClientCredits.h" // Interface declarations
28 #include <cmath>
30 #include "GetTickCount.h" // Needed for GetTickCount
31 #include "Logger.h" // Needed for Add(Debug)LogLine
33 CreditStruct::CreditStruct()
34 : uploaded(0),
35 downloaded(0),
36 nLastSeen(0),
37 nReserved3(0),
38 nKeySize(0)
40 memset(abySecureIdent, 0, MAXPUBKEYSIZE);
44 CClientCredits::CClientCredits(CreditStruct* in_credits)
46 m_pCredits = in_credits;
47 InitalizeIdent();
48 m_dwUnSecureWaitTime = 0;
49 m_dwSecureWaitTime = 0;
50 m_dwWaitTimeIP = 0;
54 CClientCredits::CClientCredits(const CMD4Hash& key)
56 m_pCredits = new CreditStruct();
57 m_pCredits->key = key;
59 InitalizeIdent();
60 m_dwUnSecureWaitTime = ::GetTickCount();
61 m_dwSecureWaitTime = ::GetTickCount();
62 m_dwWaitTimeIP = 0;
66 CClientCredits::~CClientCredits()
68 delete m_pCredits;
72 void CClientCredits::AddDownloaded(uint32 bytes, uint32 dwForIP, bool cryptoavail)
74 switch (GetCurrentIdentState(dwForIP)) {
75 case IS_IDFAILED:
76 case IS_IDBADGUY:
77 case IS_IDNEEDED:
78 if (cryptoavail) {
79 return;
81 break;
82 case IS_NOTAVAILABLE:
83 case IS_IDENTIFIED:
84 break;
87 m_pCredits->downloaded += bytes;
91 void CClientCredits::AddUploaded(uint32 bytes, uint32 dwForIP, bool cryptoavail)
93 switch (GetCurrentIdentState(dwForIP)) {
94 case IS_IDFAILED:
95 case IS_IDBADGUY:
96 case IS_IDNEEDED:
97 if (cryptoavail) {
98 return;
100 break;
101 case IS_NOTAVAILABLE:
102 case IS_IDENTIFIED:
103 break;
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)) {
126 case IS_IDFAILED:
127 case IS_IDBADGUY:
128 case IS_IDNEEDED:
129 if (cryptoavail) {
130 // bad guy - no credits for you
131 return 1.0f;
133 break;
134 case IS_NOTAVAILABLE:
135 case IS_IDENTIFIED:
136 break;
139 if (GetDownloadedTotal() < 1000000) {
140 return 1.0f;
143 float result = 0.0f;
144 if (!GetUploadedTotal()) {
145 result = 10.0f;
146 } else {
147 result = (GetDownloadedTotal() * 2.0f) / GetUploadedTotal();
150 float result2 = sqrt((GetDownloadedTotal() / 1048576.0) + 2.0f);
151 if (result > result2) {
152 result = result2;
155 if (result < 1.0f) {
156 return 1.0f;
157 } else if (result > 10.0f) {
158 return 10.0f;
161 return result;
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
175 m_nPublicKeyLen = 0;
176 m_identState = IS_NOTAVAILABLE;
178 else{
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;
185 m_dwIdentIP = 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 AddDebugLogLineM( false, 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 ) {
211 return false;
213 memcpy(m_abyPublicKey,pachIdent, nIdentLen);
214 m_nPublicKeyLen = nIdentLen;
215 m_identState = IS_IDNEEDED;
216 return true;
220 EIdentState CClientCredits::GetCurrentIdentState(uint32 dwForIP) const
222 if (m_identState != IS_IDENTIFIED)
223 return m_identState;
224 else{
225 if (dwForIP == m_dwIdentIP)
226 return IS_IDENTIFIED;
227 else
228 return IS_IDBADGUY;
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;
248 else{ // bad boy
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