Ejemplo n.º 1
0
Archivo: Fw.cs Proyecto: phoenixyj/F2B
        private void Add(string filter, long expiration, byte[] hash, FirewallConditions conds, UInt64 weight, bool permit, bool persistent, Func <string, FirewallConditions, UInt64, bool, bool, ulong> AddFilter)
        {
            long   currtime   = DateTime.UtcNow.Ticks;
            string filterName = FwData.EncodeName(expiration, hash);

            lock (dataLock)
            {
                // we need unique expiration time to keep all required
                // data in simple key/value hashmap structure (and we
                // really don't care about different expiration time in ns)
                while (cleanup.ContainsKey(expiration))
                {
                    expiration++;
                }

                // filter out requests with expiration within 10% time
                // range and treat them as duplicate requests
                UInt64 filterId = 0;
                long   expirationOld;
                if (expire.TryGetValue(hash, out expirationOld))
                {
                    if (currtime > Math.Max(expirationOld, expiration))
                    {
                        Log.Info("Skipping request with expiration in past");
                    }
                    else if (expiration < expirationOld)
                    {
                        Log.Info("Skipping request with new expiration " + expiration + " < existing exipration " + expirationOld);
                    }
                    else if (expiration - expirationOld < (expiration - currtime) / 10)
                    {
                        Log.Info("Skipping request with expiration of new records within 10% of expiration of existing rule (c/o/e=" + currtime + "/" + expirationOld + "/" + expiration + ")");
                    }
                    else
                    {
                        UInt64 filterIdOld = cleanup[expirationOld];

                        Log.Info("Replace old filter #" + filterIdOld + " with increased expiration time (c/o/e=" + currtime + "/" + expirationOld + "/" + expiration + ")");
                        try
                        {
                            filterId = AddFilter(filterName, conds, weight, permit, persistent);
                            Log.Info("Added filter rule #" + filterId + ": " + filter);
                            F2B.Firewall.Instance.Remove(filterIdOld);
                            Log.Info("Removed filter rule #" + filterIdOld);
                        }
                        catch (FirewallException ex)
                        {
                            Log.Warn("Unable to replace filter rule #" + filterId + ": " + ex.Message);
                            //fail++;
                        }

                        if (filterId != 0) // no exception during rule addition
                        {
                            data.Remove(filterIdOld);
                            expire.Remove(hash); // not necessary
                            cleanup.Remove(expirationOld);
                        }
                    }
                }
                else
                {
                    if (MaxSize == 0 || MaxSize > data.Count)
                    {
                        try
                        {
                            filterId = AddFilter(filterName, conds, weight, permit, persistent);
                            Log.Info("Added new filter #" + filterId + ": " + filter);
                        }
                        catch (FirewallException ex)
                        {
                            Log.Warn("Unable to add filter " + filter + ": " + ex.Message);
                            //fail++;
                        }
                    }
                    else
                    {
                        Log.Warn("Reached limit for number of active F2B filter rules, skipping new additions");
                    }
                }

                if (filterId != 0)
                {
                    data[filterId]      = hash;
                    expire[hash]        = expiration;
                    cleanup[expiration] = filterId;

                    if (!tCleanupExpired.Enabled)
                    {
                        Log.Info("Enabling cleanup timer (interval " + tCleanupExpired.Interval + " ms)");
                        tCleanupExpired.Enabled = true;
                    }
                }
            } // dataLock
        }