The rate limit cache entry.
Esempio n. 1
0
        /// <summary>
        /// The rate limit.
        /// </summary>
        /// <param name="hostname">
        /// The hostname.
        /// </param>
        /// <param name="channel">
        /// The channel.
        /// </param>
        /// <returns>
        /// true if rate limited, false otherwise
        /// </returns>
        private bool RateLimit(string hostname, string channel)
        {
            if (string.IsNullOrEmpty(hostname) || string.IsNullOrEmpty(channel))
            {
                // sanity check - this probably chanserv.
                this.logger.Error("JoinMessage ratelimiting called with null channel or null hostname!");
                return true;
            }

            try
            {
                // TODO: rate limiting needs to be tidyed up a bit
                lock (this.rateLimitCache)
                {
                    if (!this.rateLimitCache.ContainsKey(channel))
                    {
                        this.rateLimitCache.Add(channel, new Cache());
                    }

                    var channelCache = this.rateLimitCache[channel];

                    if (channelCache.ContainsKey(hostname))
                    {
                        this.logger.Debug("Rate limit key found.");

                        var cacheEntry = channelCache[hostname];

                        if (cacheEntry.Expiry.AddMinutes(RateLimitDuration) >= DateTime.Now)
                        {
                            this.logger.Debug("Rate limit key NOT expired.");

                            if (cacheEntry.Counter >= RateLimitMax)
                            {
                                this.logger.Debug("Rate limit HIT");

                                // RATE LIMITED!
                                return true;
                            }

                            this.logger.Debug("Rate limit incremented.");

                            // increment counter
                            cacheEntry.Counter++;
                        }
                        else
                        {
                            this.logger.Debug("Rate limit key is expired, resetting to new value.");

                            // Cache expired
                            cacheEntry.Expiry = DateTime.Now;
                            cacheEntry.Counter = 1;
                        }
                    }
                    else
                    {
                        this.logger.Debug("Rate limit not found, creating key.");

                        // Not in cache.
                        var cacheEntry = new RateLimitCacheEntry { Expiry = DateTime.Now, Counter = 1 };
                        channelCache.Add(hostname, cacheEntry);
                    }

                    // Clean up the channel's cache.
                    foreach (var key in channelCache.Keys.ToList())
                    {
                        if (channelCache[key].Expiry.AddMinutes(RateLimitDuration) < DateTime.Now)
                        {
                            // Expired.
                            channelCache.Remove(key);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // ooh dear. Something went wrong with rate limiting.
                this.logger.Error("Unknown error during rate limit processing.", ex);
                return false;
            }

            return false;
        }
Esempio n. 2
0
        /// <summary>
        /// The rate limit.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private bool RateLimit()
        {
            if (this.Source == null || this.Source.Hostname == null)
            {
                this.Log.Error("Rate limiting called with no source or no source hostname!");
                return true;
            }

            // TODO: rate limiting needs to be tidyed up a bit
            lock (RateLimitCache)
            {
                if (RateLimitCache.ContainsKey(this.Source.Hostname))
                {
                    this.Log.Debug("Rate limit key found.");

                    var cacheEntry = RateLimitCache[this.Source.Hostname];

                    if (cacheEntry.Expiry.AddMinutes(RateLimitDuration) >= DateTime.Now)
                    {
                        this.Log.Debug("Rate limit key NOT expired.");

                        if (cacheEntry.Counter >= RateLimitMax)
                        {
                            this.Log.Debug("Rate limit HIT");

                            // RATE LIMITED!
                            return true;
                        }

                        this.Log.Debug("Rate limit incremented.");

                        // increment counter
                        cacheEntry.Counter++;
                    }
                    else
                    {
                        this.Log.Debug("Rate limit key is expired, resetting to new value.");

                        // Cache expired
                        cacheEntry.Expiry = DateTime.Now;
                        cacheEntry.Counter = 1;
                    }
                }
                else
                {
                    this.Log.Debug("Rate limit not found, creating key.");

                    // Not in cache.
                    var cacheEntry = new RateLimitCacheEntry { Expiry = DateTime.Now, Counter = 1 };
                    RateLimitCache.Add(this.Source.Hostname, cacheEntry);
                }

                // Clean up the cache
                foreach (var key in RateLimitCache.Keys.ToList())
                {
                    if (RateLimitCache[key].Expiry.AddMinutes(RateLimitDuration) < DateTime.Now)
                    {
                        // Expired.
                        RateLimitCache.Remove(key);
                    }
                }
            }

            return false;
        }