/// <summary> /// Starts connecting to best target. /// </summary> private void BeginConnect() { // No tagets, abort relay. if (m_pTargets.Count == 0) { LogText("No relay target(s) for '" + m_pRelayItem.To + "', aborting."); Dispose(new Exception("No relay target(s) for '" + m_pRelayItem.To + "', aborting.")); return; } // If maximum connections to specified target exceeded and there are more targets, try to get limit free target. if (m_pServer.MaxConnectionsPerIP > 0) { // For DNS or load-balnced smart host relay, search free target if any. if (m_pServer.RelayMode == Relay_Mode.Dns || m_pServer.SmartHostsBalanceMode == BalanceMode.LoadBalance) { foreach (Relay_Target t in m_pTargets) { // We found free target, stop searching. if (m_pServer.TryAddIpUsage(m_pTargets[0].Target.Address)) { m_pActiveTarget = t; m_pTargets.Remove(t); break; } } } // Smart host fail-over mode, just check if it's free. else { // Smart host IP limit not reached. if (m_pServer.TryAddIpUsage(m_pTargets[0].Target.Address)) { m_pActiveTarget = m_pTargets[0]; m_pTargets.RemoveAt(0); } } } // Just get first target. else { m_pActiveTarget = m_pTargets[0]; m_pTargets.RemoveAt(0); } // If all targets has exeeded maximum allowed connection per IP address, end relay session, // next relay cycle will try to relay again. if (m_pActiveTarget == null) { LogText("All targets has exeeded maximum allowed connection per IP address, skip relay."); Dispose(new Exception("All targets has exeeded maximum allowed connection per IP address, skip relay.")); return; } m_pSmtpClient.BeginConnect(new IPEndPoint(m_pLocalBindInfo.IP, 0), m_pActiveTarget.Target, false, new AsyncCallback(this.ConnectCallback), null); }