/// <summary> /// Raises <b>SessionCompleted</b> event. /// </summary> /// <param name="session">Session what completed processing.</param> /// <param name="exception">Exception happened or null if relay completed successfully.</param> protected internal virtual void OnSessionCompleted(Relay_Session session, Exception exception) { if (SessionCompleted != null) { SessionCompleted(new Relay_SessionCompletedEventArgs(session, exception)); } }
/// <summary> /// Default constructor. /// </summary> /// <param name="session">Relay session what completed processing.</param> /// <param name="exception">Exception what happened or null if relay completed successfully.</param> /// <exception cref="ArgumentNullException">Is raised when <b>session</b> is null.</exception> public Relay_SessionCompletedEventArgs(Relay_Session session, Exception exception) { if (session == null) { throw new ArgumentNullException("session"); } m_pSession = session; m_pException = exception; }
/// <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_pLocalEndPoints.Clear(); foreach (IPBindInfo binding in m_pBindings) { if (binding.IP == IPAddress.Any) { foreach (IPAddress ip in Dns.GetHostAddresses("")) { if (ip.AddressFamily == AddressFamily.InterNetwork) { IPBindInfo b = new IPBindInfo(binding.HostName, binding.Protocol, ip, 25); if (!m_pLocalEndPoints.Contains(b)) { m_pLocalEndPoints.Add(b); } } } } else if (binding.IP == IPAddress.IPv6Any) { foreach (IPAddress ip in Dns.GetHostAddresses("")) { if (ip.AddressFamily == AddressFamily.InterNetworkV6) { IPBindInfo b = new IPBindInfo(binding.HostName, binding.Protocol, ip, 25); if (!m_pLocalEndPoints.Contains(b)) { m_pLocalEndPoints.Add(b); } } } } else { IPBindInfo b = new IPBindInfo(binding.HostName, binding.Protocol, binding.IP, 25); if (!m_pLocalEndPoints.Contains(b)) { m_pLocalEndPoints.Add(b); } } } m_HasBindingsChanged = false; } // There are no local end points specified. if (m_pLocalEndPoints.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 { // Get round-robin local end point for that session. // This ensures if multiple network connections, all will be load balanced. IPBindInfo localBindInfo = m_pLocalEndPoints.Next(); if (m_RelayMode == Relay_Mode.Dns) { Relay_Session session = new Relay_Session(this, localBindInfo, item); m_pSessions.Add(session); ThreadPool.QueueUserWorkItem(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, localBindInfo, item, smartHosts); m_pSessions.Add(session); ThreadPool.QueueUserWorkItem(session.Start); } } } } catch (Exception x) { OnError(x); } } }