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(); }
/// <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); }
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(); }
/// <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(); }
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); }
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."); }
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."); }
/// <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; }
/// <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); }
private MessageSender() { MantaCoreEvents.RegisterStopRequiredInstance(this); }
private RabbitMqInboundStagingHandler() { MantaCoreEvents.RegisterStopRequiredInstance(this); }