// // This file is part of the aMule Project. // // Copyright (c) 2003-2006 aMule Team ( admin@amule.org / http://www.amule.org ) // Copyright (c) 2002 Merkur ( devs@emule-project.net / http://www.emule-project.net ) // // Any parts of this program derived from the xMule, lMule or eMule project, // or contributed by third-party developers are copyrighted by their // respective authors. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // #include "ClientCredits.h" // Interface declarations #include #include "GetTickCount.h" // Needed for GetTickCount #include "Logger.h" // Needed for Add(Debug)LogLine #include "amule.h" // Needed for theApp CreditStruct::CreditStruct() : nUploadedLo(0), nDownloadedLo(0), nLastSeen(0), nUploadedHi(0), nDownloadedHi(0), nReserved3(0), nKeySize(0) { memset(abySecureIdent, 0, MAXPUBKEYSIZE); } CClientCredits::CClientCredits(CreditStruct* in_credits) { m_pCredits = in_credits; InitalizeIdent(); m_dwUnSecureWaitTime = 0; m_dwSecureWaitTime = 0; m_dwWaitTimeIP = 0; } CClientCredits::CClientCredits(const CMD4Hash& key) { m_pCredits = new CreditStruct(); m_pCredits->key = key; InitalizeIdent(); m_dwUnSecureWaitTime = ::GetTickCount(); m_dwSecureWaitTime = ::GetTickCount(); m_dwWaitTimeIP = 0; } CClientCredits::~CClientCredits() { delete m_pCredits; } void CClientCredits::AddDownloaded(uint32 bytes, uint32 dwForIP, bool cryptoavail) { if ( ( GetCurrentIdentState(dwForIP) == IS_IDFAILED || GetCurrentIdentState(dwForIP) == IS_IDBADGUY || GetCurrentIdentState(dwForIP) == IS_IDNEEDED) && cryptoavail ){ return; } //encode uint64 current=m_pCredits->nDownloadedHi; current=(current<<32)+ m_pCredits->nDownloadedLo + bytes ; //recode m_pCredits->nDownloadedLo=(uint32)current; m_pCredits->nDownloadedHi=(uint32)(current>>32); } void CClientCredits::AddUploaded(uint32 bytes, uint32 dwForIP, bool cryptoavail) { if ( ( GetCurrentIdentState(dwForIP) == IS_IDFAILED || GetCurrentIdentState(dwForIP) == IS_IDBADGUY || GetCurrentIdentState(dwForIP) == IS_IDNEEDED) && cryptoavail ){ return; } //encode uint64 current=m_pCredits->nUploadedHi; current=(current<<32)+ m_pCredits->nUploadedLo + bytes ; //recode m_pCredits->nUploadedLo=(uint32)current; m_pCredits->nUploadedHi=(uint32)(current>>32); } uint64 CClientCredits::GetUploadedTotal() const { return ( (uint64)m_pCredits->nUploadedHi<<32)+m_pCredits->nUploadedLo; } uint64 CClientCredits::GetDownloadedTotal() const { return ( (uint64)m_pCredits->nDownloadedHi<<32)+m_pCredits->nDownloadedLo; } float CClientCredits::GetScoreRatio(uint32 dwForIP, bool cryptoavail) { // check the client ident status if ( ( GetCurrentIdentState(dwForIP) == IS_IDFAILED || GetCurrentIdentState(dwForIP) == IS_IDBADGUY || GetCurrentIdentState(dwForIP) == IS_IDNEEDED) && cryptoavail ){ // bad guy - no credits for you return 1; } if (GetDownloadedTotal() < 1000000) return 1; float result = 0; if (!GetUploadedTotal()) result = 10; else result = (float)(((double)GetDownloadedTotal()*2.0)/(double)GetUploadedTotal()); float result2 = 0; result2 = (float)GetDownloadedTotal()/1048576.0; result2 += 2; result2 = (double)sqrt((double)result2); if (result > result2) result = result2; if (result < 1) return 1; else if (result > 10) return 10; return result; } void CClientCredits::SetLastSeen() { m_pCredits->nLastSeen = time(NULL); } void CClientCredits::InitalizeIdent(){ if (m_pCredits->nKeySize == 0 ){ memset(m_abyPublicKey,0,80); // for debugging m_nPublicKeyLen = 0; m_identState = IS_NOTAVAILABLE; } else{ m_nPublicKeyLen = m_pCredits->nKeySize; memcpy(m_abyPublicKey, m_pCredits->abySecureIdent, m_nPublicKeyLen); m_identState = IS_IDNEEDED; } m_dwCryptRndChallengeFor = 0; m_dwCryptRndChallengeFrom = 0; m_dwIdentIP = 0; } void CClientCredits::Verified(uint32 dwForIP){ m_dwIdentIP = dwForIP; // client was verified, copy the keyto store him if not done already if (m_pCredits->nKeySize == 0){ m_pCredits->nKeySize = m_nPublicKeyLen; memcpy(m_pCredits->abySecureIdent, m_abyPublicKey, m_nPublicKeyLen); if (GetDownloadedTotal() > 0){ // for security reason, we have to delete all prior credits here m_pCredits->nDownloadedHi = 0; m_pCredits->nDownloadedLo = 1; m_pCredits->nUploadedHi = 0; m_pCredits->nUploadedLo = 1; // in order to safe this client, set 1 byte AddDebugLogLineM( false, logCredits, wxT("Credits deleted due to new SecureIdent") ); } } m_identState = IS_IDENTIFIED; } bool CClientCredits::SetSecureIdent(const byte* pachIdent, uint8 nIdentLen){ // verified Public key cannot change, use only if there is not public key yet if (MAXPUBKEYSIZE < nIdentLen || m_pCredits->nKeySize != 0 ) { return false; } memcpy(m_abyPublicKey,pachIdent, nIdentLen); m_nPublicKeyLen = nIdentLen; m_identState = IS_IDNEEDED; return true; } EIdentState CClientCredits::GetCurrentIdentState(uint32 dwForIP) const { if (m_identState != IS_IDENTIFIED) return m_identState; else{ if (dwForIP == m_dwIdentIP) return IS_IDENTIFIED; else return IS_IDBADGUY; // mod note: clients which just reconnected after an IP change and have to ident yet will also have this state for 1-2 seconds // so don't try to spam such clients with "bad guy" messages (besides: spam messages are always bad) } } uint32 CClientCredits::GetSecureWaitStartTime(uint32 dwForIP){ if (m_dwUnSecureWaitTime == 0 || m_dwSecureWaitTime == 0) SetSecWaitStartTime(dwForIP); if (m_pCredits->nKeySize != 0){ // this client is a SecureHash Client if (GetCurrentIdentState(dwForIP) == IS_IDENTIFIED){ // good boy return m_dwSecureWaitTime; } else{ // not so good boy if (dwForIP == m_dwWaitTimeIP){ return m_dwUnSecureWaitTime; } else{ // bad boy // this can also happen if the client has not identified himself yet, but will do later - so maybe he is not a bad boy :) . m_dwUnSecureWaitTime = ::GetTickCount(); m_dwWaitTimeIP = dwForIP; return m_dwUnSecureWaitTime; } } } else{ // not a SecureHash Client - handle it like before for now (no security checks) return m_dwUnSecureWaitTime; } } void CClientCredits::SetSecWaitStartTime(uint32 dwForIP){ m_dwUnSecureWaitTime = ::GetTickCount()-1; m_dwSecureWaitTime = ::GetTickCount()-1; m_dwWaitTimeIP = dwForIP; } void CClientCredits::ClearWaitStartTime(){ m_dwUnSecureWaitTime = 0; m_dwSecureWaitTime = 0; }