void CAICHRecoveryHashSet::DbgTest(){ #ifdef _DEBUG //define TESTSIZE 4294567295 uint8 maxLevel = 0; uint32 cHash = 1; uint8 curLevel = 0; //uint32 cParts = 0; maxLevel = 0; /* CAICHHashTree* pTest = new CAICHHashTree(TESTSIZE, true, 9728000); for (uint64 i = 0; i+9728000 < TESTSIZE; i += 9728000){ CAICHHashTree* pTest2 = new CAICHHashTree(9728000, true, EMBLOCKSIZE); pTest->ReplaceHashTree(i, 9728000, &pTest2); cParts++; } CAICHHashTree* pTest2 = new CAICHHashTree(TESTSIZE-i, true, EMBLOCKSIZE); pTest->ReplaceHashTree(i, (TESTSIZE-i), &pTest2); cParts++; */ #define TESTSIZE m_pHashTree.m_nDataSize if (m_pHashTree.m_nDataSize <= EMBLOCKSIZE) return; CAICHRecoveryHashSet TestHashSet(m_pOwner); TestHashSet.SetFileSize(m_pOwner->GetFileSize()); TestHashSet.SetMasterHash(GetMasterHash(), AICH_VERIFIED); CSafeMemFile file; uint64 i; for (i = 0; i+9728000 < TESTSIZE; i += 9728000){ VERIFY( CreatePartRecoveryData(i, &file) ); /*uint32 nRandomCorruption = (rand() * rand()) % (file.GetLength()-4); file.Seek(nRandomCorruption, CFile::begin); file.Write(&nRandomCorruption, 4);*/ file.SeekToBegin(); VERIFY( TestHashSet.ReadRecoveryData(i, &file) ); file.SeekToBegin(); TestHashSet.FreeHashSet(); uint32 j; for (j = 0; j+EMBLOCKSIZE < 9728000; j += EMBLOCKSIZE){ VERIFY( m_pHashTree.FindHash(i+j, EMBLOCKSIZE, &curLevel) ); //TRACE(_T("%u - %s\r\n"), cHash, m_pHashTree.FindHash(i+j, EMBLOCKSIZE, &curLevel)->m_Hash.GetString()); maxLevel = max(curLevel, maxLevel); curLevel = 0; cHash++; } VERIFY( m_pHashTree.FindHash(i+j, 9728000-j, &curLevel) ); //TRACE(_T("%u - %s\r\n"), cHash, m_pHashTree.FindHash(i+j, 9728000-j, &curLevel)->m_Hash.GetString()); maxLevel = max(curLevel, maxLevel); curLevel = 0; cHash++; } VERIFY( CreatePartRecoveryData(i, &file) ); file.SeekToBegin(); VERIFY( TestHashSet.ReadRecoveryData(i, &file) ); file.SeekToBegin(); TestHashSet.FreeHashSet(); uint64 j; for (j = 0; j+EMBLOCKSIZE < TESTSIZE-i; j += EMBLOCKSIZE){ VERIFY( m_pHashTree.FindHash(i+j, EMBLOCKSIZE, &curLevel) ); //TRACE(_T("%u - %s\r\n"), cHash,m_pHashTree.FindHash(i+j, EMBLOCKSIZE, &curLevel)->m_Hash.GetString()); maxLevel = max(curLevel, maxLevel); curLevel = 0; cHash++; } //VERIFY( m_pHashTree.FindHash(i+j, (TESTSIZE-i)-j, &curLevel) ); TRACE(_T("%u - %s\r\n"), cHash,m_pHashTree.FindHash(i+j, (TESTSIZE-i)-j, &curLevel)->m_Hash.GetString()); maxLevel = max(curLevel, maxLevel); #endif }
void CAICHRecoveryHashSet::UntrustedHashReceived(const CAICHHash& Hash, uint32 dwFromIP){ switch(GetStatus()){ case AICH_EMPTY: case AICH_UNTRUSTED: case AICH_TRUSTED: break; default: return; } bool bFound = false; bool bAdded = false; for (int i = 0; i < m_aUntrustedHashs.GetCount(); i++){ if (m_aUntrustedHashs[i].m_Hash == Hash){ bAdded = m_aUntrustedHashs[i].AddSigningIP(dwFromIP, false); bFound = true; break; } } if (!bFound) { for (int i = 0; i < m_aUntrustedHashs.GetCount(); i++) { if (!m_aUntrustedHashs[i].AddSigningIP(dwFromIP, true)) { AddDebugLogLine(DLP_LOW, false, _T("Received different AICH hashs for file %s from IP/20 %s, ignored"), (m_pOwner != NULL) ? m_pOwner->GetFileName() : _T(""), dwFromIP); // nothing changed, so we can return early without any rechecks return; } } bAdded = true; CAICHUntrustedHash uhToAdd; uhToAdd.m_Hash = Hash; uhToAdd.AddSigningIP(dwFromIP, false); m_aUntrustedHashs.Add(uhToAdd); } uint32 nSigningIPsTotal = 0; // unique clients who send us a hash int nMostTrustedPos = (-1); // the hash which most clients send us uint32 nMostTrustedIPs = 0; for (uint32 i = 0; i < (uint32)m_aUntrustedHashs.GetCount(); i++){ nSigningIPsTotal += m_aUntrustedHashs[i].m_adwIpsSigning.GetCount(); if ((uint32)m_aUntrustedHashs[i].m_adwIpsSigning.GetCount() > nMostTrustedIPs){ nMostTrustedIPs = m_aUntrustedHashs[i].m_adwIpsSigning.GetCount(); nMostTrustedPos = i; } } if (nMostTrustedPos == (-1) || nSigningIPsTotal == 0){ ASSERT( false ); return; } // the check if we trust any hash if ( thePrefs.IsTrustingEveryHash() || (nMostTrustedIPs >= MINUNIQUEIPS_TOTRUST && (100 * nMostTrustedIPs)/nSigningIPsTotal >= MINPERCENTAGE_TOTRUST)){ //trusted //theApp.QueueDebugLogLine(false, _T("AICH Hash received: %s (%sadded), We have now %u hash from %u unique IPs. We trust the Hash %s from %u clients (%u%%). Added IP:%s, file: %s") //, Hash.GetString(), bAdded? _T(""):_T("not "), m_aUntrustedHashs.GetCount(), nSigningIPsTotal, m_aUntrustedHashs[nMostTrustedPos].m_Hash.GetString() //, nMostTrustedIPs, (100 * nMostTrustedIPs)/nSigningIPsTotal, ipstr(dwFromIP & 0x00F0FFFF), m_pOwner->GetFileName()); SetStatus(AICH_TRUSTED); if (!HasValidMasterHash() || GetMasterHash() != m_aUntrustedHashs[nMostTrustedPos].m_Hash){ SetMasterHash(m_aUntrustedHashs[nMostTrustedPos].m_Hash, AICH_TRUSTED); FreeHashSet(); } } else{ // untrusted //theApp.QueueDebugLogLine(false, _T("AICH Hash received: %s (%sadded), We have now %u hash from %u unique IPs. Best Hash (%s) is from %u clients (%u%%) - but we dont trust it yet. Added IP:%s, file: %s") // , Hash.GetString(), bAdded? _T(""):_T("not "), m_aUntrustedHashs.GetCount(), nSigningIPsTotal, m_aUntrustedHashs[nMostTrustedPos].m_Hash.GetString() // , nMostTrustedIPs, (100 * nMostTrustedIPs)/nSigningIPsTotal, ipstr(dwFromIP & 0x00F0FFFF), m_pOwner->GetFileName()); SetStatus(AICH_UNTRUSTED); if (!HasValidMasterHash() || GetMasterHash() != m_aUntrustedHashs[nMostTrustedPos].m_Hash){ SetMasterHash(m_aUntrustedHashs[nMostTrustedPos].m_Hash, AICH_UNTRUSTED); FreeHashSet(); } } }
void CAICHHashSet::UntrustedHashReceived(const CAICHHash& Hash, uint32 dwFromIP) { switch(GetStatus()) { case AICH_EMPTY: case AICH_UNTRUSTED: case AICH_TRUSTED: break; default: return; } bool bFound = false; bool bAdded = false; for (uint32 i = 0; i < m_aUntrustedHashs.size(); ++i) { if (m_aUntrustedHashs[i].m_Hash == Hash) { bAdded = m_aUntrustedHashs[i].AddSigningIP(dwFromIP); bFound = true; break; } } if (!bFound) { bAdded = true; CAICHUntrustedHash uhToAdd; uhToAdd.m_Hash = Hash; uhToAdd.AddSigningIP(dwFromIP); m_aUntrustedHashs.push_back(uhToAdd); } uint32 nSigningIPsTotal = 0; // unique clients who send us a hash int nMostTrustedPos = (-1); // the hash which most clients send us uint32 nMostTrustedIPs = 0; for (uint32 i = 0; i < (uint32)m_aUntrustedHashs.size(); ++i) { nSigningIPsTotal += m_aUntrustedHashs[i].m_adwIpsSigning.size(); if ((uint32)m_aUntrustedHashs[i].m_adwIpsSigning.size() > nMostTrustedIPs) { nMostTrustedIPs = m_aUntrustedHashs[i].m_adwIpsSigning.size(); nMostTrustedPos = i; } } if (nMostTrustedPos == (-1) || nSigningIPsTotal == 0) { wxFAIL; return; } // the check if we trust any hash if ( thePrefs::IsTrustingEveryHash() || (nMostTrustedIPs >= MINUNIQUEIPS_TOTRUST && (100 * nMostTrustedIPs)/nSigningIPsTotal >= MINPERCENTAGE_TOTRUST)) { //trusted AddDebugLogLineM(false, logSHAHashSet, CFormat(wxT("AICH Hash received (%sadded), We have now %u hash(es) from %u unique IP(s). ") wxT("We trust the Hash %s from %u client(s) (%u%%). File: %s")) % (bAdded ? wxT("") : wxT("not ")) % m_aUntrustedHashs.size() % nSigningIPsTotal % m_aUntrustedHashs[nMostTrustedPos].m_Hash.GetString() % nMostTrustedIPs % ((100 * nMostTrustedIPs) / nSigningIPsTotal) % m_pOwner->GetFileName()); SetStatus(AICH_TRUSTED); if (!HasValidMasterHash() || GetMasterHash() != m_aUntrustedHashs[nMostTrustedPos].m_Hash) { SetMasterHash(m_aUntrustedHashs[nMostTrustedPos].m_Hash, AICH_TRUSTED); FreeHashSet(); } } else { // untrusted AddDebugLogLineM(false, logSHAHashSet, CFormat(wxT("AICH Hash received (%sadded), We have now %u hash(es) from %u unique IP(s). ") wxT("Best Hash %s from %u clients (%u%%) - but we dont trust it yet. File: %s")) % (bAdded ? wxT(""): wxT("not ")) % m_aUntrustedHashs.size() % nSigningIPsTotal % m_aUntrustedHashs[nMostTrustedPos].m_Hash.GetString() % nMostTrustedIPs % ((100 * nMostTrustedIPs) / nSigningIPsTotal) % m_pOwner->GetFileName()); SetStatus(AICH_UNTRUSTED); if (!HasValidMasterHash() || GetMasterHash() != m_aUntrustedHashs[nMostTrustedPos].m_Hash) { SetMasterHash(m_aUntrustedHashs[nMostTrustedPos].m_Hash, AICH_UNTRUSTED); FreeHashSet(); } } }