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#include "ClientCredits.h" // Interface declarations 27 28#include <cmath> 29 30#include "GetTickCount.h" // Needed for GetTickCount 31#include "Logger.h" // Needed for Add(Debug)LogLine 32 33CreditStruct::CreditStruct() 34 : uploaded(0), 35 downloaded(0), 36 nLastSeen(0), 37 nReserved3(0), 38 nKeySize(0) 39{ 40 memset(abySecureIdent, 0, MAXPUBKEYSIZE); 41} 42 43 44CClientCredits::CClientCredits(CreditStruct* in_credits) 45{ 46 m_pCredits = in_credits; 47 InitalizeIdent(); 48 m_dwUnSecureWaitTime = 0; 49 m_dwSecureWaitTime = 0; 50 m_dwWaitTimeIP = 0; 51} 52 53 54CClientCredits::CClientCredits(const CMD4Hash& key) 55{ 56 m_pCredits = new CreditStruct(); 57 m_pCredits->key = key; 58 59 InitalizeIdent(); 60 m_dwUnSecureWaitTime = ::GetTickCount(); 61 m_dwSecureWaitTime = ::GetTickCount(); 62 m_dwWaitTimeIP = 0; 63} 64 65 66CClientCredits::~CClientCredits() 67{ 68 delete m_pCredits; 69} 70 71 72void CClientCredits::AddDownloaded(uint32 bytes, uint32 dwForIP, bool cryptoavail) 73{ 74 switch (GetCurrentIdentState(dwForIP)) { 75 case IS_IDFAILED: 76 case IS_IDBADGUY: 77 case IS_IDNEEDED: 78 if (cryptoavail) { 79 return; 80 } 81 break; 82 case IS_NOTAVAILABLE: 83 case IS_IDENTIFIED: 84 break; 85 } 86 87 m_pCredits->downloaded += bytes; 88} 89 90 91void CClientCredits::AddUploaded(uint32 bytes, uint32 dwForIP, bool cryptoavail) 92{ 93 switch (GetCurrentIdentState(dwForIP)) { 94 case IS_IDFAILED: 95 case IS_IDBADGUY: 96 case IS_IDNEEDED: 97 if (cryptoavail) { 98 return; 99 } 100 break; 101 case IS_NOTAVAILABLE: 102 case IS_IDENTIFIED: 103 break; 104 } 105 106 m_pCredits->uploaded += bytes; 107} 108 109 110uint64 CClientCredits::GetUploadedTotal() const 111{ 112 return m_pCredits->uploaded; 113} 114 115 116uint64 CClientCredits::GetDownloadedTotal() const 117{ 118 return m_pCredits->downloaded; 119} 120 121 122float CClientCredits::GetScoreRatio(uint32 dwForIP, bool cryptoavail) 123{ 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; 132 } 133 break; 134 case IS_NOTAVAILABLE: 135 case IS_IDENTIFIED: 136 break; 137 } 138 139 if (GetDownloadedTotal() < 1000000) { 140 return 1.0f; 141 } 142 143 float result = 0.0f; 144 if (!GetUploadedTotal()) { 145 result = 10.0f; 146 } else { 147 result = (GetDownloadedTotal() * 2.0f) / GetUploadedTotal(); 148 } 149 150 float result2 = sqrt((GetDownloadedTotal() / 1048576.0) + 2.0f); 151 if (result > result2) { 152 result = result2; 153 } 154 155 if (result < 1.0f) { 156 return 1.0f; 157 } else if (result > 10.0f) { 158 return 10.0f; 159 } 160 161 return result; 162} 163 164 165void CClientCredits::SetLastSeen() 166{ 167 m_pCredits->nLastSeen = time(NULL); 168} 169 170 171void CClientCredits::InitalizeIdent() 172{ 173 if (m_pCredits->nKeySize == 0 ){ 174 memset(m_abyPublicKey,0,80); // for debugging 175 m_nPublicKeyLen = 0; 176 m_identState = IS_NOTAVAILABLE; 177 } 178 else{ 179 m_nPublicKeyLen = m_pCredits->nKeySize; 180 memcpy(m_abyPublicKey, m_pCredits->abySecureIdent, m_nPublicKeyLen); 181 m_identState = IS_IDNEEDED; 182 } 183 m_dwCryptRndChallengeFor = 0; 184 m_dwCryptRndChallengeFrom = 0; 185 m_dwIdentIP = 0; 186} 187 188 189void CClientCredits::Verified(uint32 dwForIP) 190{ 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") ); 202 } 203 } 204 m_identState = IS_IDENTIFIED; 205} 206 207 208bool 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; 212 } 213 memcpy(m_abyPublicKey,pachIdent, nIdentLen); 214 m_nPublicKeyLen = nIdentLen; 215 m_identState = IS_IDNEEDED; 216 return true; 217} 218 219 220EIdentState CClientCredits::GetCurrentIdentState(uint32 dwForIP) const 221{ 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) 231 } 232} 233 234 235uint32 CClientCredits::GetSecureWaitStartTime(uint32 dwForIP) 236{ 237 if (m_dwUnSecureWaitTime == 0 || m_dwSecureWaitTime == 0) 238 SetSecWaitStartTime(dwForIP); 239 240 if (m_pCredits->nKeySize != 0){ // this client is a SecureHash Client 241 if (GetCurrentIdentState(dwForIP) == IS_IDENTIFIED){ // good boy 242 return m_dwSecureWaitTime; 243 } 244 else{ // not so good boy 245 if (dwForIP == m_dwWaitTimeIP){ 246 return m_dwUnSecureWaitTime; 247 } 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 :) . 250 251 m_dwUnSecureWaitTime = ::GetTickCount(); 252 m_dwWaitTimeIP = dwForIP; 253 return m_dwUnSecureWaitTime; 254 } 255 } 256 } 257 else{ // not a SecureHash Client - handle it like before for now (no security checks) 258 return m_dwUnSecureWaitTime; 259 } 260} 261 262 263void CClientCredits::SetSecWaitStartTime(uint32 dwForIP) 264{ 265 m_dwUnSecureWaitTime = ::GetTickCount()-1; 266 m_dwSecureWaitTime = ::GetTickCount()-1; 267 m_dwWaitTimeIP = dwForIP; 268} 269 270 271void CClientCredits::ClearWaitStartTime() 272{ 273 m_dwUnSecureWaitTime = 0; 274 m_dwSecureWaitTime = 0; 275} 276 277// File_checked_for_headers 278