Exemplo n.º 1
0
Arquivo: Fw.cs Projeto: phoenixyj/F2B
        public void Add(FwData fwdata, UInt64 weight = 0, bool permit = false, bool persistent = false)
        {
            long expiration = fwdata.Expire;
            long currtime   = DateTime.UtcNow.Ticks;

            // Adding filter with expiration time in past
            // doesn't really make any sense
            if (currtime >= expiration)
            {
                string tmp = Convert.ToString(expiration);
                try
                {
                    DateTime tmpExp = new DateTime(expiration, DateTimeKind.Utc);
                    tmp = tmpExp.ToLocalTime().ToString();
                }
                catch (Exception)
                {
                }
                Log.Info("Skipping expired firewall rule (expired on " + tmp + ")");
                return;
            }

            byte[]             hash  = fwdata.Hash;
            FirewallConditions conds = fwdata.Conditions();

            // IPv4 filter layer
            if (conds.HasIPv4() || (!conds.HasIPv4() && !conds.HasIPv6()))
            {
                byte[] hash4 = new byte[hash.Length];
                hash.CopyTo(hash4, 0);
                hash4[hash4.Length - 1] &= 0xfe;
                Add(fwdata.ToString(), expiration, hash4, conds, weight, permit, persistent, F2B.Firewall.Instance.AddIPv4);
            }

            // IPv6 filter layer
            if (conds.HasIPv6() || (!conds.HasIPv4() && !conds.HasIPv6()))
            {
                byte[] hash6 = new byte[hash.Length];
                hash.CopyTo(hash6, 0);
                hash6[hash6.Length - 1] |= 0x01;
                Add(fwdata.ToString(), expiration, hash6, conds, weight, permit, persistent, F2B.Firewall.Instance.AddIPv6);
            }
        }
Exemplo n.º 2
0
Arquivo: Fw.cs Projeto: 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
        }