/// <summary> /// Stores message for relay. /// </summary> /// <param name="queueName">Queue name where to store message.</param> /// <param name="id">Message ID. Guid value is suggested.</param> /// <param name="envelopeID">Envelope ID_(MAIL FROM: ENVID).</param> /// <param name="date">Message date.</param> /// <param name="message">Message to store. Message will be readed from current position of stream.</param> /// <param name="targetHost">Target host or IP where to send message. This value can be null, then DNS MX o A record is used to deliver message.</param> /// <param name="sender">Sender address to report to target server.</param> /// <param name="to">Message recipient address.</param> /// <param name="originalRecipient">Original recipient(RCPT TO: ORCPT).</param> /// <param name="notify">DSN notify condition.</param> /// <param name="ret">Specifies what parts of message are returned in DSN report.</param> /// <exception cref="ArgumentNullException">Is raised when <b>queueName</b>,<b>id</b>,<b>message</b> or <b>to</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the argumnets has invalid value.</exception> private void StoreRelayMessage(string queueName, string id, string envelopeID, DateTime date, Stream message, HostEndPoint targetHost, string sender, string to, string originalRecipient, SMTP_DSN_Notify notify, SMTP_DSN_Ret ret) { if (queueName == null) { throw new ArgumentNullException("queueName"); } if (queueName == "") { throw new ArgumentException("Argumnet 'queueName' value must be specified."); } if (id == null) { throw new ArgumentNullException("id"); } if (id == "") { throw new ArgumentException("Argument 'id' value must be specified."); } if (message == null) { throw new ArgumentNullException("message"); } if (to == null) { throw new ArgumentNullException("to"); } if (to == "") { throw new ArgumentException("Argument 'to' value must be specified."); } string path = m_pVirtualServer.MailStorePath + queueName; // Check if Directory exists, if not Create if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } // Create relay message. using (FileStream fs = File.Create(API_Utlis.PathFix(path + "\\" + id + ".eml"))) { SCore.StreamCopy(message, fs); // Create message info file for the specified relay message. RelayMessageInfo messageInfo = new RelayMessageInfo( envelopeID, sender, to, originalRecipient, notify, ret, date, false, targetHost ); File.WriteAllBytes(API_Utlis.PathFix(path + "\\" + id + ".info"), messageInfo.ToByte()); } }
/// <summary> /// This loop method processes "Relay Retry" messages while server is running. /// </summary> private void ProcessRelayRetry() { DateTime lastRelayTime = DateTime.MinValue; while (this.IsRunning) { try{ // Relay interval reached, relay available messages. if (lastRelayTime.AddSeconds(m_RelayRetryInterval) < DateTime.Now) { string path = m_pVirtualServer.MailStorePath + "Retry"; if (Directory.Exists(path)) { string[] messages = Directory.GetFiles(path, "*.eml"); foreach (string message in messages) { // Relay server maximum connections exceeded, we have maxConnections + 25 messages. // Just wait when some messge completes processing. while (this.Queues[1].Count > 25) { if (!this.IsRunning) { return; } Thread.Sleep(100); } try{ string messageID = Path.GetFileNameWithoutExtension(message); FileStream messageStream = File.Open(message, FileMode.Open, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete); if (File.Exists(API_Utlis.PathFix(path + "\\" + messageID + ".info"))) { RelayMessageInfo messageInfo = RelayMessageInfo.Parse(File.ReadAllBytes(API_Utlis.PathFix(path + "\\" + messageID + ".info"))); // Queue message for relay. this.Queues[1].QueueMessage( messageInfo.Sender, messageInfo.Recipient, messageID, messageStream, messageInfo ); } // Relay message info file missing. else { LumiSoft.MailServer.Error.DumpError(m_pVirtualServer.Name, new Exception("Relay message '" + message + "' .info file is missing, deleting message.")); File.Delete(message); } } catch (IOException x) { // Message file is in use, probably is relayed now or being stored for relay, skip it. string dummy = x.Message; } } } lastRelayTime = DateTime.Now; // We need to sleep, because if relay interval = 0, loop will consume all CPU. Thread.Sleep(1000); } // Not a relay interval yet, sleep. else { Thread.Sleep(1000); } } catch (Exception x) { LumiSoft.MailServer.Error.DumpError(m_pVirtualServer.Name, x); } } }