Example #1
0
        /// <summary>
        /// Smart host relay session constructor.
        /// </summary>
        /// <param name="server">Owner relay server.</param>
        /// <param name="realyItem">Relay item.</param>
        /// <param name="smartHosts">Smart hosts.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>server</b>,<b>realyItem</b> or <b>smartHosts</b>is null.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        internal Relay_Session(Relay_Server server, Relay_QueueItem realyItem, Relay_SmartHost[] smartHosts)
        {
            if (server == null)
            {
                throw new ArgumentNullException("server");
            }
            if (realyItem == null)
            {
                throw new ArgumentNullException("realyItem");
            }
            if (smartHosts == null)
            {
                throw new ArgumentNullException("smartHosts");
            }

            m_pServer     = server;
            m_pRelayItem  = realyItem;
            m_pSmartHosts = smartHosts;

            m_RelayMode         = Relay_Mode.SmartHost;
            m_SessionID         = Guid.NewGuid().ToString();
            m_SessionCreateTime = DateTime.Now;
            m_pTargets          = new List <Relay_Target>();
            m_pSmtpClient       = new SMTP_Client();
        }
Example #2
0
        /// <summary>
        /// Completes relay session and does clean up. This method is thread-safe.
        /// </summary>
        /// <param name="exception">Exception happened or null if relay completed successfully.</param>
        public void Dispose(Exception exception)
        {
            try{
                lock (this){
                    if (m_IsDisposed)
                    {
                        return;
                    }
                    try{
                        m_pServer.OnSessionCompleted(this, exception);
                    }
                    catch {
                    }
                    m_pServer.Sessions.Remove(this);
                    m_IsDisposed = true;

                    m_pLocalBindInfo = null;
                    m_pRelayItem     = null;
                    m_pSmartHosts    = null;
                    if (m_pSmtpClient != null)
                    {
                        m_pSmtpClient.Dispose();
                        m_pSmtpClient = null;
                    }
                    m_pTargets = null;
                    if (m_pActiveTarget != null)
                    {
                        m_pServer.RemoveIpUsage(m_pActiveTarget.Target.Address);
                        m_pActiveTarget = null;
                    }
                    m_pServer = null;
                }
            }
            catch (Exception x) {
                if (m_pServer != null)
                {
                    m_pServer.OnError(x);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Processes relay queue.
        /// </summary>
        private void Run()
        {
            while (m_IsRunning)
            {
                try
                {
                    // Bind info has changed, create new local end points.
                    if (m_HasBindingsChanged)
                    {
                        m_pLocalEndPointIPv4.Clear();
                        m_pLocalEndPointIPv6.Clear();

                        foreach (IPBindInfo binding in m_pBindings)
                        {
                            if (binding.IP == IPAddress.Any)
                            {
                                foreach (IPAddress ip in System.Net.Dns.GetHostAddresses(""))
                                {
                                    if (ip.AddressFamily == AddressFamily.InterNetwork)
                                    {
                                        IPBindInfo b = new IPBindInfo(binding.HostName, binding.Protocol, ip, 25);
                                        if (!m_pLocalEndPointIPv4.Contains(b))
                                        {
                                            m_pLocalEndPointIPv4.Add(b);
                                        }
                                    }
                                }
                            }
                            else if (binding.IP == IPAddress.IPv6Any)
                            {
                                foreach (IPAddress ip in System.Net.Dns.GetHostAddresses(""))
                                {
                                    if (ip.AddressFamily == AddressFamily.InterNetworkV6)
                                    {
                                        IPBindInfo b = new IPBindInfo(binding.HostName, binding.Protocol, ip, 25);
                                        if (!m_pLocalEndPointIPv6.Contains(b))
                                        {
                                            m_pLocalEndPointIPv6.Add(b);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                IPBindInfo b = new IPBindInfo(binding.HostName, binding.Protocol, binding.IP, 25);
                                if (binding.IP.AddressFamily == AddressFamily.InterNetwork)
                                {
                                    if (!m_pLocalEndPointIPv4.Contains(b))
                                    {
                                        m_pLocalEndPointIPv4.Add(b);
                                    }
                                }
                                else
                                {
                                    if (!m_pLocalEndPointIPv6.Contains(b))
                                    {
                                        m_pLocalEndPointIPv6.Add(b);
                                    }
                                }
                            }
                        }

                        m_HasBindingsChanged = false;
                    }

                    // There are no local end points specified.
                    if (m_pLocalEndPointIPv4.Count == 0 && m_pLocalEndPointIPv6.Count == 0)
                    {
                        Thread.Sleep(10);
                    }
                    // Maximum allowed relay sessions exceeded, skip adding new ones.
                    else if (m_MaxConnections != 0 && m_pSessions.Count >= m_MaxConnections)
                    {
                        Thread.Sleep(10);
                    }
                    else
                    {
                        Relay_QueueItem item = null;

                        // Get next queued message from highest possible priority queue.
                        foreach (Relay_Queue queue in m_pQueues)
                        {
                            item = queue.DequeueMessage();
                            // There is queued message.
                            if (item != null)
                            {
                                break;
                            }
                            // No messages in this queue, see next lower priority queue.
                        }

                        // There are no messages in any queue.
                        if (item == null)
                        {
                            Thread.Sleep(10);
                        }
                        // Create new session for queued relay item.
                        else
                        {
                            // Relay item has relay target server specified.
                            if (item.TargetServer != null)
                            {
                                Relay_Session session = new Relay_Session(this, item, new Relay_SmartHost[] { item.TargetServer });
                                m_pSessions.Add(session);
                                ThreadPool.QueueUserWorkItem(new WaitCallback(session.Start));
                            }
                            else if (m_RelayMode == Relay_Mode.Dns)
                            {
                                Relay_Session session = new Relay_Session(this, item);
                                m_pSessions.Add(session);
                                ThreadPool.QueueUserWorkItem(new WaitCallback(session.Start));
                            }
                            else if (m_RelayMode == Relay_Mode.SmartHost)
                            {
                                // Get smart hosts in balance mode order.
                                Relay_SmartHost[] smartHosts = null;
                                if (m_SmartHostsBalanceMode == BalanceMode.FailOver)
                                {
                                    smartHosts = m_pSmartHosts.ToArray();
                                }
                                else
                                {
                                    smartHosts = m_pSmartHosts.ToCurrentOrderArray();
                                }

                                Relay_Session session = new Relay_Session(this, item, smartHosts);
                                m_pSessions.Add(session);
                                ThreadPool.QueueUserWorkItem(new WaitCallback(session.Start));
                            }
                        }
                    }
                }
                catch (Exception x)
                {
                    OnError(x);
                }
            }
        }