public static void RecheckFirewalled() { if (m_pInstance != null && m_pInstance.GetPrefs() != null && !IsRunningInLANMode()) { // Something is forcing a new firewall check // Stop any new buddy requests, and tell the client // to recheck it's IP which in turns rechecks firewall. m_pInstance.m_pPrefs.SetFindBuddy(false); m_pInstance.m_pPrefs.SetRecheckIP(); // also UDP check UDPFirewallTester.ReCheckFirewallUDP(false); DateTime tNow = DateTime.Now; // Delay the next buddy search to at least 5 minutes after our firewallcheck so we are sure to be still firewalled m_tNextFindBuddy = (m_tNextFindBuddy < tNow.AddMinutes(5)) ? (tNow.AddMinutes(5)) : m_tNextFindBuddy; m_tNextFirewallCheck = tNow.AddHours(1); m_tNextUPnPCheck = m_tNextFirewallCheck.AddMinutes(-1); } }
private static uint CalculateKadUsersNew() { // the idea of calculating the user count with this method is simple: // whenever we do search for any NodeID (except in certain cases were the result is not usable), // we remember the distance of the closest node we found. Because we assume all NodeIDs are distributed // equally, we can calcualte based on this distance how "filled" the possible NodesID room is and by this // calculate how many users there are. Of course this only works if we have enough samples, because // each single sample will be wrong, but the average of them should produce a usable number. To avoid // drifts caused by a a single (or more) really close or really far away hits, we do use median-average instead through // doesnt works well if we have no files to index and nothing to download and the numbers seems to be a bit too low // compared to out other method. So lets stay with the old one for now, but keeps this here as alternative if (m_liStatsEstUsersProbes.Count < 10) { return(0); } uint nMedian = 0; List <uint> liMedian; foreach (uint nProbe in m_liStatsEstUsersProbes) { bool bInserted = false; for (POSITION pos2 = liMedian.GetHeadPosition(); pos2 != null; liMedian.GetNext(pos2)) { if (liMedian[pos2] > nProbe) { liMedian.InsertBefore(pos2, nProbe); bInserted = true; break; } } if (!bInserted) { liMedian.AddTail(nProbe); } } // cut away 1/3 of the values - 1/6 of the top and 1/6 of the bottom to avoid spikes having too much influence, build the average of the rest sint32 nCut = liMedian.Count / 6; for (int i = 0; i != nCut; i++) { liMedian.RemoveHead(); liMedian.RemoveTail(); } ulong nAverage = 0; for (POSITION pos1 = liMedian.GetHeadPosition(); pos1 != NULL;) { nAverage += liMedian.GetNext(pos1); } nMedian = (uint)(nAverage / liMedian.GetCount()); // 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 outself (the actual Firewalled count at this date on kad is 35-55%) const float fFirewalledModifyOld = 1.20F; float fFirewalledModifyNew = 0; if (UDPFirewallTester.IsFirewalledUDP(true)) { fFirewalledModifyNew = 1.40F; // we are firewalled and get get the real statistic, assume 40% firewalled >=0.49b nodes } else if (GetPrefs().StatsGetFirewalledRatio(true) > 0) { fFirewalledModifyNew = 1.0F + (GetPrefs().StatsGetFirewalledRatio(true)); // apply the firewalled ratio to the modify Debug.Assert(fFirewalledModifyNew > 1.0F && fFirewalledModifyNew < 1.90F); } float fNewRatio = GetPrefs().KadV8Ratio; float fFirewalledModifyTotal = 0; if (fNewRatio > 0 && fFirewalledModifyNew > 0) // weigth the old and the new modifier based on how many new contacts we have { fFirewalledModifyTotal = (fNewRatio * fFirewalledModifyNew) + ((1 - fNewRatio) * fFirewalledModifyOld); } else { fFirewalledModifyTotal = fFirewalledModifyOld; } Debug.Assert(fFirewalledModifyTotal > 1.0F && fFirewalledModifyTotal < 1.90F); return((uint)((float)nMedian * fFirewalledModifyTotal)); }
public static void Process() { if (m_pInstance == null || !m_bRunning) { return; } bool bUpdateUserFile = false; uint uMaxUsers = 0; uint uTempUsers = 0; uint uLastContact = 0; DateTime tNow = DateTime.Now; Debug.Assert(m_pInstance.m_pPrefs != null); uLastContact = m_pInstance.m_pPrefs.GetLastContact(); SearchManager.UpdateStats(); if (m_tStatusUpdate <= tNow) { bUpdateUserFile = true; m_tStatusUpdate = tNow.AddMinutes(1); } if (m_tNextFirewallCheck <= tNow) { RecheckFirewalled(); } if (m_tNextUPnPCheck != DateTime.MinValue && m_tNextUPnPCheck <= tNow) { theApp.emuledlg.RefreshUPnP(); m_tNextUPnPCheck = DateTime.MinValue; // will be reset on firewallcheck } if (m_tNextSelfLookup <= tNow) { SearchManager.FindNode(m_pInstance.m_pPrefs.GetKadID(), true); m_tNextSelfLookup = tNow.AddHours(4); } if (m_tNextFindBuddy <= tNow) { m_pInstance.m_pPrefs.SetFindBuddy(); m_tNextFindBuddy = tNow.AddMinutes(20); } if (m_tExternPortLookup <= tNow && UDPFirewallTester.IsFWCheckUDPRunning() && GetPrefs().FindExternKadPort(false)) { // if our UDP firewallcheck is running and we don't know our external port, we send a request every 15 seconds Contact pContact = GetRoutingZone().GetRandomContact(3, Opcodes.KADEMLIA_VERSION6_49aBETA); if (pContact != null) { //DEBUG_ONLY(DebugLog("Requesting our external port from %s", IPAddress.Parse(IPAddress.NetworkToHostOrder(pContact.IPAddress).ToString()).ToString())); GetUDPListener().SendNullPacket(Opcodes.KADEMLIA2_PING, pContact.IPAddress, pContact.UDPPort, pContact.UDPKey, &pContact.ClientID); } else { DEBUG_ONLY(DebugLogWarning("No valid client for requesting external port available")); } m_tExternPortLookup = tNow.AddMilliseconds(15); } foreach (RoutingZone pZone in m_mapEvents.Values) { if (bUpdateUserFile) { // The EstimateCount function is not made for really small networks, if we are in LAN mode, it is actually // better to assume that all users of the network are in our routingtable and use the real count function if (IsRunningInLANMode()) { uTempUsers = pZone.GetNumContacts(); } else { uTempUsers = pZone.EstimateCount(); } if (uMaxUsers < uTempUsers) { uMaxUsers = uTempUsers; } } if (m_tBigTimer <= tNow) { if (pZone.m_tNextBigTimer <= tNow) { if (pZone.OnBigTimer()) { pZone.m_tNextBigTimer = tNow.AddHours(1); m_tBigTimer = tNow.AddSeconds(10); } } else { if (uLastContact && ((tNow - uLastContact) > (Opcodes.KADEMLIADISCONNECTDELAY - Opcodes.MIN2S(5)))) { if (pZone.OnBigTimer()) { pZone.m_tNextBigTimer = tNow.AddHours(1); m_tBigTimer = tNow.AddSeconds(10); } } } } if (pZone.m_tNextSmallTimer <= tNow) { pZone.OnSmallTimer(); pZone.m_tNextSmallTimer = tNow.AddMinutes(1); } } // This is a convenient place to add this, although not related to routing if (m_tNextSearchJumpStart <= tNow) { SearchManager.JumpStart(); m_tNextSearchJumpStart = tNow.AddMilliseconds(Defines.SEARCH_JUMPSTART); } // Try to consolidate any zones that are close to empty. if (m_tConsolidate <= tNow) { uint uMergedCount = m_pInstance.m_pRoutingZone.Consolidate(); if (uMergedCount > 0) { AddDebugLogLine(false, "Kad merged %u Zones", uMergedCount); } m_tConsolidate = tNow.AddMinutes(45); } //Update user count only if changed. if (bUpdateUserFile) { if (uMaxUsers != m_pInstance.m_pPrefs.GetKademliaUsers()) { m_pInstance.m_pPrefs.SetKademliaUsers(uMaxUsers); m_pInstance.m_pPrefs.SetKademliaFiles(); theApp.emuledlg.ShowUserCount(); } } if (!IsConnected() && !s_liBootstapList.IsEmpty() && ((tNow - m_tBootstrap).Milliseconds > 15 || (GetRoutingZone().GetNumContacts() == 0 && (tNow - m_tBootstrap).Milliseconds >= 2))) { Contact pContact = s_liBootstapList.RemoveHead(); m_tBootstrap = tNow; //DebugLog("Trying to Bootstrap Kad from %s, Distance: %s, Version: %u, %u Contacts left", ipstr(ntohl(pContact->GetIPAddress())), pContact->GetDistance().ToHexString(), pContact->GetVersion(), s_liBootstapList.GetCount()); m_pInstance.m_pUDPListener.Bootstrap(pContact.IPAddress, pContact.UDPPort, pContact.Version, pContact.ClientID); } if (GetUDPListener() != null) { GetUDPListener().ExpireClientSearch(); // function does only one compare in most cases, so no real need for a timer } }