Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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
            }
        }