Exemplo n.º 1
0
        protected override void OnStart(string[] args)
        {
            Logging.Info("Starting OpenManta Service.");
            AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
            {
                Exception ex = (Exception)e.ExceptionObject;
                Logging.Fatal(ex.Message, ex);
            };

            RabbitMqInboundStagingHandler.Start();

            // Start the RabbitMQ Bulk inserter.
            QueueManager.Instance.Start();

            // Create the SmtpServers
            foreach (var vmta in VirtualMtaManager.GetVirtualMtasForListeningOn())
            {
                foreach (var port in MtaParameters.ServerListeningPorts)
                {
                    SmtpServers.Add(new SmtpServer(vmta.IPAddress, port));
                }
            }

            // Start the SMTP Client.
            MessageSender.Instance.Start();

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

            Logging.Info("OpenManta Service has started.");
        }
Exemplo n.º 2
0
        protected override void OnStart(string[] args)
        {
            RabbitMqInboundStagingHandler.Start();

            Logging.Info("Starting Manta MTA Service.");

            AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
            {
                Exception ex = (Exception)e.ExceptionObject;
                Logging.Fatal(ex.Message, ex);
            };

            // Start the RabbitMQ Bulk inserter.
            QueueManager.Instance.Start();

            VirtualMTACollection ipAddresses = VirtualMtaManager.GetVirtualMtasForListeningOn();

            // 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();

            Logging.Info("Manta MTA Service has started.");
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        private async Task <bool> SendMessageAsync(MtaQueuedMessage msg)
        {
            // Check that the message next attempt after has passed.
            if (msg.AttemptSendAfterUtc > DateTime.UtcNow)
            {
                RabbitMqOutboundQueueManager.Enqueue(msg);
                await Task.Delay(50);                 // To prevent a tight loop within a Task thread we should sleep here.

                return(false);
            }

            if (await MtaTransaction.HasBeenHandledAsync(msg.ID))
            {
                msg.IsHandled = true;
                return(true);
            }

            // Get the send that this message belongs to so that we can check the send state.
            Send snd = await SendManager.Instance.GetSendAsync(msg.InternalSendID);

            switch (snd.SendStatus)
            {
            // The send is being discarded so we should discard the message.
            case SendStatus.Discard:
                await msg.HandleMessageDiscardAsync();

                return(false);

            // The send is paused, the handle pause state will delay, without deferring, the message for a while so we can move on to other messages.
            case SendStatus.Paused:
                msg.HandleSendPaused();
                return(false);

            // Send is active so we don't need to do anything.
            case SendStatus.Active:
                break;

            // Unknown send state, requeue the message and log error. Cannot send!
            default:
                msg.AttemptSendAfterUtc = DateTime.UtcNow.AddMinutes(1);
                RabbitMqOutboundQueueManager.Enqueue(msg);
                Logging.Error("Failed to send message. Unknown SendStatus[" + snd.SendStatus + "]!");
                return(false);
            }


            bool result;

            // Check the message hasn't timed out. If it has don't attempt to send it.
            // Need to do this here as there may be a massive backlog on the server
            // causing messages to be waiting for ages after there AttemptSendAfter
            // before picking up. The MAX_TIME_IN_QUEUE should always be enforced.
            if (msg.AttemptSendAfterUtc - msg.QueuedTimestampUtc > new TimeSpan(0, MtaParameters.MtaMaxTimeInQueue, 0))
            {
                await msg.HandleDeliveryFailAsync(MtaParameters.TIMED_OUT_IN_QUEUE_MESSAGE, null, null);

                result = false;
            }
            else
            {
                MailAddress mailAddress = new MailAddress(msg.RcptTo[0]);
                MailAddress mailFrom    = new MailAddress(msg.MailFrom);
                MXRecord[]  mXRecords   = DNSManager.GetMXRecords(mailAddress.Host);
                // If mxs is null then there are no MX records.
                if (mXRecords == null || mXRecords.Length < 1)
                {
                    await msg.HandleDeliveryFailAsync("550 Domain Not Found.", null, null);

                    result = false;
                }
                else if (IsMxBlacklisted(mXRecords))
                {
                    await msg.HandleDeliveryFailAsync("550 Domain blacklisted.", null, mXRecords[0]);

                    result = false;
                }
                else
                {
                    // The IP group that will be used to send the queued message.
                    VirtualMtaGroup virtualMtaGroup = VirtualMtaManager.GetVirtualMtaGroup(msg.VirtualMTAGroupID);
                    VirtualMTA      sndIpAddress    = virtualMtaGroup.GetVirtualMtasForSending(mXRecords[0]);

                    SmtpOutboundClientDequeueResponse dequeueResponse = await SmtpClientPool.Instance.DequeueAsync(sndIpAddress, mXRecords);

                    switch (dequeueResponse.DequeueResult)
                    {
                    case SmtpOutboundClientDequeueAsyncResult.Success:
                    case SmtpOutboundClientDequeueAsyncResult.NoMxRecords:
                    case SmtpOutboundClientDequeueAsyncResult.FailedToAddToSmtpClientQueue:
                    case SmtpOutboundClientDequeueAsyncResult.Unknown:
                        break;                                 // Don't need to do anything for these results.

                    case SmtpOutboundClientDequeueAsyncResult.FailedToConnect:
                        await msg.HandleFailedToConnectAsync(sndIpAddress, mXRecords[0]);

                        break;

                    case SmtpOutboundClientDequeueAsyncResult.ServiceUnavalible:
                        await msg.HandleServiceUnavailableAsync(sndIpAddress);

                        break;

                    case SmtpOutboundClientDequeueAsyncResult.Throttled:
                        await msg.HandleDeliveryThrottleAsync(sndIpAddress, mXRecords[0]);

                        break;

                    case SmtpOutboundClientDequeueAsyncResult.FailedMaxConnections:
                        msg.AttemptSendAfterUtc = DateTime.UtcNow.AddSeconds(2);
                        RabbitMqOutboundQueueManager.Enqueue(msg);
                        break;
                    }

                    SmtpOutboundClient smtpClient = dequeueResponse.SmtpOutboundClient;

                    // If no client was dequeued then we can't currently send.
                    // This is most likely a max connection issue. Return false but don't
                    // log any deferal or throttle.
                    if (smtpClient == null)
                    {
                        result = false;
                    }
                    else
                    {
                        try
                        {
                            Action <string> failedCallback = delegate(string smtpResponse)
                            {
                                // If smtpRespose starts with 5 then perm error should cause fail
                                if (smtpResponse.StartsWith("5"))
                                {
                                    msg.HandleDeliveryFailAsync(smtpResponse, sndIpAddress, smtpClient.MXRecord).Wait();
                                }
                                else
                                {
                                    // If the MX is actively denying use service access, SMTP code 421 then we should inform
                                    // the ServiceNotAvailableManager manager so it limits our attepts to this MX to 1/minute.
                                    if (smtpResponse.StartsWith("421"))
                                    {
                                        ServiceNotAvailableManager.Add(smtpClient.SmtpStream.LocalAddress.ToString(), smtpClient.MXRecord.Host, DateTime.UtcNow);
                                        msg.HandleDeliveryDeferral(smtpResponse, sndIpAddress, smtpClient.MXRecord, true);
                                    }
                                    else
                                    {
                                        // Otherwise message is deferred
                                        msg.HandleDeliveryDeferral(smtpResponse, sndIpAddress, smtpClient.MXRecord, false);
                                    }
                                }
                                throw new SmtpTransactionFailedException();
                            };
                            // Run each SMTP command after the last.
                            await smtpClient.ExecHeloOrRsetAsync(failedCallback);

                            await smtpClient.ExecMailFromAsync(mailFrom, failedCallback);

                            await smtpClient.ExecRcptToAsync(mailAddress, failedCallback);

                            await smtpClient.ExecDataAsync(msg.Message, failedCallback, async (response) => {
                                await msg.HandleDeliverySuccessAsync(sndIpAddress, smtpClient.MXRecord, response);
                            });

                            SmtpClientPool.Instance.Enqueue(smtpClient);

                            result = true;
                        }
                        catch (SmtpTransactionFailedException)
                        {
                            // Exception is thrown to exit transaction, logging of deferrals/failers already handled.
                            result = false;
                        }
                        catch (Exception ex)
                        {
                            Logging.Error("MessageSender error.", ex);
                            if (msg != null)
                            {
                                msg.HandleDeliveryDeferral("Connection was established but ended abruptly.", sndIpAddress, smtpClient.MXRecord, false);
                            }
                            result = false;
                        }
                        finally
                        {
                            if (smtpClient != null)
                            {
                                smtpClient.IsActive   = false;
                                smtpClient.LastActive = DateTime.UtcNow;
                            }
                        }
                    }
                }
            }
            return(result);
        }