public SmtpSession(SmtpConnection connection, ISmtpResponderFactory responderFactory) : base(connection) { if (responderFactory == null) throw new ArgumentNullException("responderFactory"); ResponderFactory = responderFactory; SessionInfo = new SmtpSessionInfo(); }
protected async Task SendGreetingAsync(SmtpConnection connectionToSendGreetingTo, string greeting) { if (connectionToSendGreetingTo == null) throw new ArgumentNullException("connectionToSendGreetingTo"); var greetingLine = "220 " + greeting; MailServerLogger.Instance.Debug(">>> " + greetingLine); await connectionToSendGreetingTo.WriteLineAsyncAndFireEvents(greetingLine); GreetingSent(this, new SmtpSessionEventArgs(connectionToSendGreetingTo.Session)); }
private async Task SetupSessionThenProcessCommands(SmtpConnection connection, SmtpSession session) { await SendGreetingAsync(connection, Greeting ?? Configuration.DefaultGreeting); var sessionInfoParseResponder = new SmtpSessionInfoResponder(session.ResponderFactory, session.SessionInfo); var rawLineDecoder = new RawLineDecoder(connection); rawLineDecoder.RequestDisconnection += (s, e) => { if (!e.DisconnectionExpected) { MailServerLogger.Instance.Warn(String.Format("Connection unexpectedly lost {0}", connection.RemoteEndPoint)); } rawLineDecoder.Cancel(); session.Disconnect(); }; rawLineDecoder.DetectedActivity += (s, e) => session.UpdateActivity(); rawLineDecoder.ProcessLineCommand += async (s, e) => { // ReSharper disable PossibleUnintendedReferenceComparison var response = sessionInfoParseResponder.ProcessLineCommand(e.Buffer); if (response == SmtpResponse.None) return; if (response == SmtpResponse.Disconnect) { await SendResponseAsync(connection, response); MailServerLogger.Instance.Debug(String.Format("Remote connection disconnected {0}", connection.RemoteEndPoint)); rawLineDecoder.Cancel(); session.Disconnect(); return; } // ReSharper restore PossibleUnintendedReferenceComparison await SendResponseAsync(connection, response); }; #pragma warning disable 4014 rawLineDecoder.ProcessCommandsAsync(); #pragma warning restore 4014 }
private static async Task SendResponseAsync(SmtpConnection connection, SmtpResponse response) { LogResponse(response); foreach (var additional in response.AdditionalLines) await connection.WriteLineAsyncAndFireEvents(additional); await connection.WriteLineAsyncAndFireEvents(response.ResponseCode + " " + response.ResponseText); }
private async void PortBindingClientConnected(PortListener serverPortBinding, TcpClient newConnectedTcpClient) { var connection = new SmtpConnection(this, serverPortBinding, newConnectedTcpClient); connection.ClientDisconnected += (sender, args) => ClientDisconnected(this, new SmtpConnectionEventArgs(args.Connection)); Connections[connection.RemoteEndPoint] = connection; ClientConnected(this, new SmtpConnectionEventArgs(connection)); await CreateSessionAndProcessCommands(connection); }
private async Task CreateSessionAndProcessCommands(SmtpConnection connection) { var session = connection.CreateSession(DefaultResponderFactory); await SetupSessionThenProcessCommands(connection, session); }
public SmtpConnectionEventArgs(SmtpConnection connection) { Connection = connection; }
private async Task SetupSessionThenProcessCommands(SmtpConnection connection, SmtpSession session) { await SendGreetingAsync(connection, Greeting ?? Configuration.DefaultGreeting); var sessionInfoParseResponder = new SmtpSessionInfoResponder(session.ResponderFactory, session.SessionInfo); var rawLineDecoder = new RawLineDecoder(connection); rawLineDecoder.RequestDisconnection += (s, e) => { if (!e.DisconnectionExpected) { MailServerLogger.Instance.Warn($"Connection unexpectedly lost {connection.RemoteEndPoint}"); } rawLineDecoder.Cancel(); session.Disconnect(); }; rawLineDecoder.DetectedActivity += (s, e) => session.UpdateActivity(); rawLineDecoder.ProcessLineCommand += async (s, e) => { var response = sessionInfoParseResponder.ProcessLineCommand(e.Buffer); if (response == null || !response.HasValue) return; if (response.ResponseCode == SmtpResponses.DisconnectResponseCode) { await SendResponseAsync(connection, response); MailServerLogger.Instance.Debug($"Remote connection disconnected {connection.RemoteEndPoint}"); rawLineDecoder.Cancel(); await Task.Delay(100).ContinueWith(t => session.Disconnect()); return; } await SendResponseAsync(connection, response); }; #pragma warning disable 4014 rawLineDecoder.ProcessCommandsAsync(); #pragma warning restore 4014 }
private static async Task SendResponseAsync(SmtpConnection connection, SmtpResponse response) { LogResponse(response); try { foreach (var additional in response.AdditionalLines) await connection.WriteLineAsyncAndFireEvents(additional); await connection.WriteLineAsyncAndFireEvents(response.ResponseCode + " " + response.ResponseText); } catch(Exception ex) { MailServerLogger.Instance.Error(ex); } }
private async void PortBindingClientConnected(PortListener serverPortBinding, TcpClient newConnectedTcpClient) { var connection = new SmtpConnection(this, serverPortBinding, newConnectedTcpClient); connection.ClientDisconnected += (sender, args) => ClientDisconnected(this, new SmtpConnectionEventArgs(args.Connection)); SmtpConnection cnn; connection.ClientDisconnected += (sender, args) => Connections.TryRemove(connection.RemoteEndPoint, out cnn); Connections[connection.RemoteEndPoint] = connection; ClientConnected(this, new SmtpConnectionEventArgs(connection)); try { await CreateSessionAndProcessCommands(connection); } catch(Exception ex) { MailServerLogger.Instance.Error(ex); } }