Пример #1
0
        /// <summary>
        /// Gets the maximum amount of simultaneous connections to specified host.
        /// </summary>
        /// <param name="ipAddress">IP Address connecting from.</param>
        /// <param name="record">MXRecord of the destination.</param>
        /// <returns>Max number of connections.</returns>
        internal static int GetMaxConnectionsToDestination(VirtualMTA ipAddress, MXRecord record)
        {
            int mxPatternID = -1;
            OutboundRuleCollection rules = OutboundRuleManager.GetRules(record, ipAddress, out mxPatternID);

            for (int i = 0; i < rules.Count; i++)
            {
                if (rules[i].Type == OutboundRuleType.MaxConnections)
                {
                    int tmp = 0;
                    if (int.TryParse(rules[i].Value, out tmp))
                    {
                        return(tmp);
                    }
                    else
                    {
                        Logging.Error("Failed to get max connections for " + record.Host + " using " + ipAddress.IPAddress.ToString() + " value wasn't valid [" + rules[i].Value + "], defaulting to 1");
                        return(1);
                    }
                }
            }

            Logging.Error("Failed to get max connections for " + record.Host + " using " + ipAddress.IPAddress.ToString() + " defaulting to 1");
            return(1);
        }
Пример #2
0
        /// <summary>
        /// Gets permission to attempt a send of a message.
        /// </summary>
        /// <param name="ipAddress">The IP Address we wan't to send from.</param>
        /// <param name="mxRecord">The MX Record of the destination.</param>
        /// <returns>TRUE if we can send FALSE if we should throttle.</returns>
        public bool TryGetSendAuth(VirtualMTA ipAddress, MXRecord mxRecord)
        {
            int mxPatternID     = -1;
            int maxMessagesHour = OutboundRuleManager.GetMaxMessagesDestinationHour(ipAddress, mxRecord, out mxPatternID);

            // If the Max messages is -1 then unlimited so can just return true here.
            // No need for any logging or calculating.
            if (maxMessagesHour == -1)
            {
                return(true);
            }

            // Create or get this outbound IP/mx pattern send history.
            ThrottleManager.MxPatternThrottlingSendHistory mxSndHist = null;
            if (!this._sendHistory.TryGetValue(ipAddress.IPAddress.ToString(), out mxSndHist))
            {
                mxSndHist = new ThrottleManager.MxPatternThrottlingSendHistory();
                this._sendHistory.AddOrUpdate(ipAddress.IPAddress.ToString(), mxSndHist, (string s, ThrottleManager.MxPatternThrottlingSendHistory sh) => mxSndHist);
            }
            //this._sendHistory.GetOrAdd(ipAddress.IPAddress.ToString(), new ThrottleManager.MxPatternThrottlingSendHistory());
            List <DateTime> sndHistory = mxSndHist.GetOrAdd(mxPatternID, new List <DateTime>());

            // Only calculate if needed.
            if (mxSndHist.IntervalValuesNeedRecalcTimestamp <= DateTime.UtcNow)
            {
                int maxMessages = 0;
                int maxMessagesIntervalMinute = 0;
                while (maxMessages < 1 && maxMessagesIntervalMinute <= 60)
                {
                    maxMessagesIntervalMinute++;
                    maxMessages = (int)Math.Floor((double)maxMessagesHour / 60d * (double)maxMessagesIntervalMinute);
                }

                mxSndHist.IntervalMaxMessages = maxMessages;
                mxSndHist.IntervalMinutes     = maxMessagesIntervalMinute;
                mxSndHist.IntervalValuesNeedRecalcTimestamp = DateTime.UtcNow.AddMinutes(MtaParameters.MTA_CACHE_MINUTES);
            }


            lock (sndHistory)
            {
                // Remove sends that happened over "Interval" minute(s) ago.
                DateTime sendsAfterTimestamp = DateTime.UtcNow.AddMinutes((double)(mxSndHist.IntervalMinutes * -1));
                sndHistory.RemoveAll((DateTime d) => d <= sendsAfterTimestamp);

                // Check for throttling
                if (sndHistory.Count < mxSndHist.IntervalMaxMessages)
                {
                    // Not hit throttle limit yet.
                    // Log send and return true.
                    sndHistory.Add(DateTime.UtcNow);
                    return(true);
                }
                else
                {
                    // THROTTLED!
                    return(false);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Gets the Outbound Rules for the specified destination MX and optionally IP Address.
        /// </summary>
        /// <param name="mxRecord">MXRecord for the destination MX.</param>
        /// <param name="mtaIpAddress">Outbound IP Address</param>
        /// <param name="mxPatternID">OUT: the ID of MxPattern that caused match.</param>
        /// <returns></returns>
        public static OutboundRuleCollection GetRules(MXRecord mxRecord, VirtualMTA mtaIpAddress, out int mxPatternID)
        {
            // Get the data from the database. This needs to be cleverer and reload every x minutes.
            if (OutboundRuleManager._MXPatterns == null)
            {
                OutboundRuleManager._MXPatterns = OutboundRuleDB.GetOutboundRulePatterns();
            }
            if (OutboundRuleManager._Rules == null)
            {
                OutboundRuleManager._Rules = OutboundRuleDB.GetOutboundRules();
            }

            int patternID = OutboundRuleManager.GetMxPatternID(mxRecord, mtaIpAddress);

            mxPatternID = patternID;
            return(new OutboundRuleCollection(
                       from r in OutboundRuleManager._Rules
                       where r.OutboundMxPatternID == patternID
                       select r));
        }
Пример #4
0
        /// <summary>
        /// Gets the maximum amount of messages to send per hour from each ip address to mx.
        /// </summary>
        /// <param name="ipAddress">Outbound IP address</param>
        /// <param name="record">MX Record of destination server.</param>
        /// <param name="mxPatternID">ID of the pattern used to identify the rule.</param>
        /// <returns>Maximum number of messages per hour or -1 for unlimited.</returns>
        public static int GetMaxMessagesDestinationHour(VirtualMTA ipAddress, MXRecord record, out int mxPatternID)
        {
            OutboundRuleCollection rules = OutboundRuleManager.GetRules(record, ipAddress, out mxPatternID);

            for (int i = 0; i < rules.Count; i++)
            {
                if (rules[i].Type == OutboundRuleType.MaxMessagesPerHour)
                {
                    int tmp = 0;
                    if (int.TryParse(rules[i].Value, out tmp))
                    {
                        return(tmp);
                    }
                    else
                    {
                        Logging.Error("Failed to get max messages per hour for " + record.Host + " using " + ipAddress.IPAddress.ToString() + " value wasn't valid [" + rules[i].Value + "], defaulting to unlimited");
                        return(-1);
                    }
                }
            }

            Logging.Error("Failed to get max messages per hour for " + record.Host + " using " + ipAddress.IPAddress.ToString() + " defaulting to unlimited");
            return(-1);
        }