Пример #1
0
        private SmtpOutboundClientCollection() : base()
        {
            // Thread responsable for removing inactive connections.
            Thread t = new Thread(new ThreadStart(delegate()
            {
                // Loop forever
                while (true)
                {
                    try
                    {
                        int removedCount = 0;

                        // Loop through all of the connections.
                        for (int i = 0; i < _Instance.Count; i++)
                        {
                            SmtpOutboundClient client = _Instance[i];
                            if (client != null &&
                                client.IsActive == false &&
                                client.LastActive.AddSeconds(MtaParameters.Client.ConnectionIdleTimeoutInterval) <= DateTime.UtcNow)
                            {
                                // The connection is not null and appears to have been inactive for the idle timeout interval.

                                try
                                {
                                    if (!client.ExecQuitAsync().Result)
                                    {
                                        if (client.Connected)
                                        {
                                            client.GetStream().Close();
                                        }
                                        client.Close();
                                    }
                                }
                                catch (Exception)
                                {
                                    client.Close();
                                }
                                finally
                                {
                                    client.Dispose();
                                }
                                i--; // ExecQuitAsync will remove from the list.
                                removedCount++;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logging.Fatal("SmtpOutboundClient idle handler failed", ex);
                        MantaCoreEvents.InvokeMantaCoreStopping();
                        Environment.Exit(-1);
                    }

                    Thread.Sleep(1000);
                }
            }));

            t.IsBackground = true;
            t.Start();
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        private MantaSmtpClientPoolCollection()
        {
            MantaCoreEvents.RegisterStopRequiredInstance(this);

            ClientPools = new Dictionary <string, MantaOutboundClientPool>();
            Task.Factory.StartNew(async() =>
            {
                do
                {
                    await Task.Delay(1000);
                    foreach (var k in ClientPools.Keys)
                    {
                        if (IsStopping)
                        {
                            break;
                        }

                        if (ClientPools[k].LastUsedTimestamp < DateTime.UtcNow.AddMinutes(-2).Ticks)
                        {
                            ClientPools.Remove(k);
                        }
                    }
                } while (!IsStopping);
            }, TaskCreationOptions.LongRunning);
        }
Пример #3
0
        private EventsFileHandler()
        {
            // EventsFileHandler needs to be stopped when MantaMTA is stopping.
            MantaCoreEvents.RegisterStopRequiredInstance(this);

            // Make sure the drop folders exist.
            Directory.CreateDirectory(MtaParameters.BounceDropFolder);
            Directory.CreateDirectory(Path.Combine(MtaParameters.BounceDropFolder, _SubdirectoryForProblemEmails));
            Directory.CreateDirectory(MtaParameters.FeedbackLoopDropFolder);
            Directory.CreateDirectory(Path.Combine(MtaParameters.FeedbackLoopDropFolder, _SubdirectoryForProblemEmails));

            // Setup and start the bounce email file watcher.
            FileSystemWatcher bounceWatcher = new FileSystemWatcher(MtaParameters.BounceDropFolder, "*.eml");

            bounceWatcher.Created            += DoBounceFileProcessing;
            bounceWatcher.EnableRaisingEvents = true;

            // Setup and start the feedback loop email file watcher.
            FileSystemWatcher abuseWatcher = new FileSystemWatcher(MtaParameters.FeedbackLoopDropFolder, "*.eml");

            abuseWatcher.Created            += DoAbuseFileProcessing;
            abuseWatcher.EnableRaisingEvents = true;

            Thread t = new Thread(new ThreadStart(delegate()
            {
                DoBounceFileProcessing(bounceWatcher, new FileSystemEventArgs(WatcherChangeTypes.All, MtaParameters.BounceDropFolder, string.Empty));
                DoAbuseFileProcessing(abuseWatcher, new FileSystemEventArgs(WatcherChangeTypes.All, MtaParameters.FeedbackLoopDropFolder, string.Empty));
            }));

            t.Start();
        }
Пример #4
0
        /// <summary>
        /// Call this method to start the EventHttpForwarder.
        /// </summary>
        public void Start()
        {
            MantaCoreEvents.RegisterStopRequiredInstance(this);
            Thread t = new Thread(new ThreadStart(ForwardEvents));

            t.IsBackground = true;
            t.Start();
        }
Пример #5
0
        static void Main(string[] args)
        {
            Logging.Info("MTA Started");

            AppDomain.CurrentDomain.FirstChanceException += delegate(object sender, FirstChanceExceptionEventArgs e)
            {
                Logging.Warn("", e.Exception);
            };

            IList <VirtualMTA> ipAddresses = VirtualMtaManager.GetVirtualMtasForListeningOn();

            // Array will hold all instances of SmtpServer, one for each port we will be listening on.
            List <SmtpServer> smtpServers = new List <SmtpServer>();

            // Create the SmtpServers
            for (int c = 0; c < ipAddresses.Count; c++)
            {
                VirtualMTA ipAddress = ipAddresses[c];
                for (int i = 0; i < MtaParameters.ServerListeningPorts.Length; i++)
                {
                    smtpServers.Add(new SmtpServer(ipAddress.IPAddress, MtaParameters.ServerListeningPorts[i]));
                }
            }

            // Start the SMTP Client.
            MessageSender.Instance.Start();
            // Start the events (bounce/abuse) handler.
            EventsFileHandler.Instance.Start();

            QueueManager.Instance.Start();
            OpenManta.Framework.RabbitMq.RabbitMqInboundStagingHandler.Start();

            bool quit = false;

            while (!quit)
            {
                ConsoleKeyInfo key = System.Console.ReadKey(true);
                if (key.KeyChar == 'q' || key.KeyChar == 'Q')
                {
                    quit = true;
                }
            }

            // Need to wait while servers & client shutdown.
            MantaCoreEvents.InvokeMantaCoreStopping();
            foreach (SmtpServer s in smtpServers)
            {
                s.Dispose();
            }

            Logging.Info("MTA Stopped");
            System.Console.WriteLine("Press any key to continue");
            System.Console.ReadKey(true);
        }
Пример #6
0
        protected override void OnStop()
        {
            Logging.Info("Stopping OpenManta Service");

            // Need to wait while servers & client shutdown.
            MantaCoreEvents.InvokeMantaCoreStopping();
            foreach (var smtp in SmtpServers)
            {
                smtp.Dispose();
            }

            Logging.Info("OpenManta Service has stopped.");
        }
Пример #7
0
        protected override void OnStop()
        {
            Logging.Info("Stopping Manta MTA Service");

            // Need to wait while servers & client shutdown.
            MantaCoreEvents.InvokeMantaCoreStopping();
            for (int i = 0; i < _SmtpServers.Count; i++)
            {
                (_SmtpServers[i] as SmtpServer).Dispose();
            }

            Logging.Info("Manta MTA Service has stopped.");
        }
Пример #8
0
        /// <summary>
        /// Does the actual forwarding of the events.
        /// </summary>
        private void ForwardEvents()
        {
            _IsRunning = true;

            try
            {
                // Keep looping as long as the MTA is running.
                while (!_IsStopping)
                {
                    MantaEventCollection events = null;
                    // Get events for forwarding.
                    try
                    {
                        events = Core.DAL.EventDB.GetEventsForForwarding(10);
                    }
                    catch (SqlNullValueException)
                    {
                        events = new MantaEventCollection();
                    }


                    if (events.Count == 0)
                    {
                        // No events to forward sleep for a second and look again.
                        Thread.Sleep(1000);
                        continue;
                    }
                    else
                    {
                        // Found events to forward, create and run Tasks to forward.
                        var eventTasks = new Task[events.Count];
                        for (var i = 0; i < events.Count; i++)
                        {
                            ForwardEventAsync(events[i]).Wait();
                        }
                        // eventTasks[0] = Task.Factory.StartNew(async (evt) => await ForwardEventAsync((MantaEvent)evt), events[i]);

                        //Task.WaitAll(eventTasks);
                    }
                }
            }
            catch (Exception ex)
            {
                // Something went wrong.
                Logging.Error("EventHttpForwarder encountered an error.", ex);
                MantaCoreEvents.InvokeMantaCoreStopping();
                Environment.Exit(-1);
            }

            _IsRunning = false;
        }
Пример #9
0
        /// <summary>
        /// Gets the MxPatternID that matches the MX Record, Outbound IP Address combo.
        /// </summary>
        /// <param name="record"></param>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        private static int GetMxPatternID(MXRecord record, VirtualMTA ipAddress)
        {
            if (_matchedPatterns == null)
            {
                _matchedPatterns = new ConcurrentDictionary <string, MatchedMxPatternCollection>();
            }

            MatchedMxPatternCollection matchedPatterns = null;

            if (!_matchedPatterns.TryGetValue(record.Host, out matchedPatterns))
            {
                matchedPatterns = new MatchedMxPatternCollection();
                _matchedPatterns.AddOrUpdate(record.Host, matchedPatterns, (string s, MatchedMxPatternCollection p) => matchedPatterns);
            }

            MatchedMxPattern matchedPattern = matchedPatterns.GetMatchedMxPattern(ipAddress);

            if (matchedPattern != null &&
                matchedPattern.MatchedUtc.AddMinutes(MtaParameters.MTA_CACHE_MINUTES) > DateTime.UtcNow)
            {
                // Found a valid cached pattern ID so return it.
                return(matchedPattern.MxPatternID);
            }

            // Loop through all of the patterns
            for (int i = 0; i < _MXPatterns.Count; i++)
            {
                // The current pattern we're working with.
                OutboundMxPattern pattern = _MXPatterns[i];

                // If the pattern applies only to a specified IP address then
                // only check for a match if getting rules for that IP.
                if (pattern.LimitedToOutboundIpAddressID.HasValue &&
                    pattern.LimitedToOutboundIpAddressID.Value != ipAddress.ID)
                {
                    continue;
                }

                if (pattern.Type == OutboundMxPatternType.CommaDelimited)
                {
                    // Pattern is a comma delimited list, so split the values
                    string[] strings = pattern.Value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    // Loop though the values in the split string array.
                    for (int c = 0; c < strings.Length; c++)
                    {
                        try
                        {
                            // If they are a match return the rules.
                            if (strings[c].Equals(record.Host, StringComparison.OrdinalIgnoreCase))
                            {
                                if (pattern.LimitedToOutboundIpAddressID.HasValue)
                                {
                                    matchedPatterns.Add(pattern.ID, ipAddress);
                                }
                                else
                                {
                                    matchedPatterns.Add(pattern.ID, null);
                                }

                                return(pattern.ID);
                            }
                        }
                        catch (Exception) { }
                    }

                    continue;
                }
                else if (pattern.Type == OutboundMxPatternType.Regex)
                {
                    // Pattern is Regex so just need to do an IsMatch
                    if (Regex.IsMatch(record.Host, pattern.Value, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture))
                    {
                        // Found pattern match.
                        if (pattern.LimitedToOutboundIpAddressID.HasValue)
                        {
                            matchedPatterns.Add(pattern.ID, ipAddress);
                        }
                        else
                        {
                            matchedPatterns.Add(pattern.ID, null);
                        }

                        return(pattern.ID);
                    }
                    else
                    {
                        continue;
                    }
                }
                else
                {
                    // Don't know what to do with this pattern so move on to the next.
                    Logging.Error("Unknown OutboundMxPatternType : " + pattern.Type.ToString());
                    continue;
                }
            }

            // Should have been found by default at least, but hasn't.
            Logging.Fatal("No MX Pattern Rules! Default Deleted?");
            MantaCoreEvents.InvokeMantaCoreStopping();
            Environment.Exit(0);
            return(-1);
        }
Пример #10
0
 private MessageSender()
 {
     MantaCoreEvents.RegisterStopRequiredInstance(this);
 }
Пример #11
0
 private RabbitMqInboundStagingHandler()
 {
     MantaCoreEvents.RegisterStopRequiredInstance(this);
 }