📄 routingzone.cpp
字号:
delete *it; } }}uint32_t CRoutingZone::Consolidate(){ uint32_t mergeCount = 0; if (IsLeaf()) { return mergeCount; } wxASSERT(m_bin == NULL); if (!m_subZones[0]->IsLeaf()) { mergeCount += m_subZones[0]->Consolidate(); } if (!m_subZones[1]->IsLeaf()) { mergeCount += m_subZones[1]->Consolidate(); } if (m_subZones[0]->IsLeaf() && m_subZones[1]->IsLeaf() && GetNumContacts() < K / 2) { m_bin = new CRoutingBin(); m_subZones[0]->StopTimer(); m_subZones[1]->StopTimer(); ContactList list0; ContactList list1; m_subZones[0]->m_bin->GetEntries(&list0); m_subZones[1]->m_bin->GetEntries(&list1); m_subZones[0]->m_bin->m_dontDeleteContacts = true; m_subZones[1]->m_bin->m_dontDeleteContacts = true; delete m_subZones[0]; delete m_subZones[1]; m_subZones[0] = NULL; m_subZones[1] = NULL; for (ContactList::const_iterator it = list0.begin(); it != list0.end(); ++it) { m_bin->AddContact(*it); } for (ContactList::const_iterator it = list1.begin(); it != list1.end(); ++it) { m_bin->AddContact(*it); } StartTimer(); mergeCount++; } return mergeCount;}CRoutingZone *CRoutingZone::GenSubZone(unsigned side){ wxASSERT(side <= 1); CUInt128 newIndex(m_zoneIndex); newIndex <<= 1; newIndex += side; return new CRoutingZone(this, m_level + 1, newIndex);}void CRoutingZone::StartTimer(){ // Start filling the tree, closest bins first. m_nextBigTimer = time(NULL) + SEC(10); CKademlia::AddEvent(this);}void CRoutingZone::StopTimer(){ CKademlia::RemoveEvent(this);}bool CRoutingZone::OnBigTimer() const{ if (IsLeaf() && (m_zoneIndex < KK || m_level < KBASE || m_bin->GetRemaining() >= (K * 0.8))) { RandomLookup(); return true; } return false;}//This is used when we find a leaf and want to know what this sample looks like.//We fall back two levels and take a sample to try to minimize any areas of the //tree that will give very bad results.uint32_t CRoutingZone::EstimateCount() const throw(){ if (!IsLeaf()) { return 0; } if (m_level < KBASE) { return (uint32_t)(pow(2.0, (int)m_level) * K); } CRoutingZone* curZone = m_superZone->m_superZone->m_superZone; // Find out how full this part of the tree is. float modify = ((float)curZone->GetNumContacts()) / (float)(K * 2); // First calculate users assuming the tree is full. // Modify count by bin size. // Modify count by how full the tree is. // LowIDModififier // Modify count by assuming 20% of the users are firewalled and can't be a contact for < 0.49b nodes // Modify count by actual statistics of Firewalled ratio for >= 0.49b if we are not firewalled ourself // Modify count by 40% for >= 0.49b if we are firewalled ourself (the actual Firewalled count at this date on kad is 35-55%) const float firewalledModifyOld = 1.20; float firewalledModifyNew = 0; if (CUDPFirewallTester::IsFirewalledUDP(true)) { firewalledModifyNew = 1.40; // we are firewalled and can't get the real statistics, assume 40% firewalled >=0.49b nodes } else if (CKademlia::GetPrefs()->StatsGetFirewalledRatio(true) > 0) { firewalledModifyNew = 1.0 + (CKademlia::GetPrefs()->StatsGetFirewalledRatio(true)); // apply the firewalled ratio to the modify wxASSERT(firewalledModifyNew > 1.0 && firewalledModifyNew < 1.90); } float newRatio = CKademlia::GetPrefs()->StatsGetKadV8Ratio(); float firewalledModifyTotal = 0; if (newRatio > 0 && firewalledModifyNew > 0) { // weight the old and the new modifier based on how many new contacts we have firewalledModifyTotal = (newRatio * firewalledModifyNew) + ((1 - newRatio) * firewalledModifyOld); } else { firewalledModifyTotal = firewalledModifyOld; } wxASSERT(firewalledModifyTotal > 1.0 && firewalledModifyTotal < 1.90); return (uint32_t)(pow(2.0, (int)m_level - 2) * (float)K * modify * firewalledModifyTotal);}void CRoutingZone::OnSmallTimer(){ if (!IsLeaf()) { return; } CContact *c = NULL; time_t now = time(NULL); ContactList entries; // Remove dead entries m_bin->GetEntries(&entries); for (ContactList::iterator it = entries.begin(); it != entries.end(); ++it) { c = *it; if (c->GetType() == 4) { if ((c->GetExpireTime() > 0) && (c->GetExpireTime() <= now)) { if (!c->InUse()) { m_bin->RemoveContact(c); delete c; } continue; } } if(c->GetExpireTime() == 0) { c->SetExpireTime(now); } } c = m_bin->GetOldest(); if (c != NULL) { if (c->GetExpireTime() >= now || c->GetType() == 4) { m_bin->PushToBottom(c); c = NULL; } } if (c != NULL) { c->CheckingType(); if (c->GetVersion() >= 6) { DebugSend(Kad2HelloReq, c->GetIPAddress(), c->GetUDPPort()); CUInt128 clientID = c->GetClientID(); CKademlia::GetUDPListener()->SendMyDetails(KADEMLIA2_HELLO_REQ, c->GetIPAddress(), c->GetUDPPort(), c->GetVersion(), c->GetUDPKey(), &clientID, false); if (c->GetVersion() >= 8) { // FIXME: // This is a bit of a work around for statistic values. Normally we only count values from incoming HELLO_REQs for // the firewalled statistics in order to get numbers from nodes which have us on their routing table, // however if we send a HELLO due to the timer, the remote node won't send a HELLO_REQ itself anymore (but // a HELLO_RES which we don't count), so count those statistics here. This isn't really accurate, but it should // do fair enough. Maybe improve it later for example by putting a flag into the contact and make the answer count CKademlia::GetPrefs()->StatsIncUDPFirewalledNodes(false); CKademlia::GetPrefs()->StatsIncTCPFirewalledNodes(false); } } else if (c->GetVersion() >= 2) { DebugSend(Kad2HelloReq, c->GetIPAddress(), c->GetUDPPort()); CKademlia::GetUDPListener()->SendMyDetails(KADEMLIA2_HELLO_REQ, c->GetIPAddress(), c->GetUDPPort(), c->GetVersion(), 0, NULL, false); wxASSERT(c->GetUDPKey() == CKadUDPKey(0)); } else { DebugSend(KadHelloReq, c->GetIPAddress(), c->GetUDPPort()); CKademlia::GetUDPListener()->SendMyDetails(KADEMLIA_HELLO_REQ, c->GetIPAddress(), c->GetUDPPort(), 0, 0, NULL, false); if (c->CheckIfKad2()) { DebugSend(Kad2HelloReq, c->GetIPAddress(), c->GetUDPPort()); CKademlia::GetUDPListener()->SendMyDetails(KADEMLIA2_HELLO_REQ, c->GetIPAddress(), c->GetUDPPort(), 1, 0, NULL, false); } } }}void CRoutingZone::RandomLookup() const{ // Look-up a random client in this zone CUInt128 prefix(m_zoneIndex); prefix <<= 128 - m_level; CUInt128 random(prefix, m_level); random ^= me; CSearchManager::FindNode(random, false);}uint32_t CRoutingZone::GetNumContacts() const throw(){ if (IsLeaf()) { return m_bin->GetSize(); } else { return m_subZones[0]->GetNumContacts() + m_subZones[1]->GetNumContacts(); }}void CRoutingZone::GetNumContacts(uint32_t& nInOutContacts, uint32_t& nInOutFilteredContacts, uint8_t minVersion) const{ if (IsLeaf()) { m_bin->GetNumContacts(nInOutContacts, nInOutFilteredContacts, minVersion); } else { m_subZones[0]->GetNumContacts(nInOutContacts, nInOutFilteredContacts, minVersion); m_subZones[1]->GetNumContacts(nInOutContacts, nInOutFilteredContacts, minVersion); }}uint32_t CRoutingZone::GetBootstrapContacts(ContactList *results, uint32_t maxRequired) const{ wxASSERT(m_superZone == NULL); results->clear(); uint32_t count = 0; ContactList top; TopDepth(LOG_BASE_EXPONENT, &top); if (top.size() > 0) { for (ContactList::const_iterator it = top.begin(); it != top.end(); ++it) { results->push_back(*it); count++; if (count == maxRequired) { break; } } } return count;}bool CRoutingZone::VerifyContact(const CUInt128& id, uint32_t ip){ CContact* contact = GetContact(id); if (contact == NULL) { return false; } else if (ip != contact->GetIPAddress()) { return false; } else { if (contact->IsIPVerified()) { AddDebugLogLineM(false, logKadRouting, wxT("Sender already verified (sender: ") + Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip)) + wxT(")")); } else { contact->SetIPVerified(true); } return true; }}void CRoutingZone::SetAllContactsVerified(){ if (IsLeaf()) { m_bin->SetAllContactsVerified(); } else { m_subZones[0]->SetAllContactsVerified(); m_subZones[1]->SetAllContactsVerified(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -