Mail is received, but the SessionCompleted event is not triggered / SessionFaulted
tinohager opened this issue · 7 comments
I can receive mails perfectly with my test mail server. The mails are stored and everything works fine. But I noticed that the SessionCompleted event is not fired. Now I have also added SessionFaulted to the log output and here I get an exception. For unsecured connections as well as secured connections.
The problem seems to occur only under Linux. I was not able to reproduce it on my Windows computer.
Secure
info: DockerMailReceiver.SmtpServerWorker[0]
SessionCreated - Port:25 IsSecure:False RemoteEndpoint:40.92.75.65
info: DockerMailReceiver.MailboxFilterFactories.DefaultMailboxFilterFactory[0]
DefaultMailboxFilterFactory - Port:25 IsSecure:True RemoteEndpoint:40.92.75.65
info: DockerMailReceiver.MailboxFilterFactories.DefaultMailboxFilterFactory[0]
DefaultMailboxFilterFactory - Port:25 IsSecure:True RemoteEndpoint:40.92.75.65
info: DockerMailReceiver.SmtpServerWorker[0]
SessionFaulted - System.IO.IOException: Unable to write data to the transport connection: Connection reset by peer.
---> System.Net.Sockets.SocketException (104): Connection reset by peer
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.CreateException(SocketError , Boolean )
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.SendAsyncForNetworkStream(Socket , CancellationToken )
at System.Net.Sockets.Socket.SendAsyncForNetworkStream(ReadOnlyMemory`1 , SocketFlags , CancellationToken )
at System.Net.Sockets.NetworkStream.WriteAsync(ReadOnlyMemory`1 , CancellationToken )
at System.Net.Security.SslStream.WriteSingleChunk[TIOAdapter](TIOAdapter , ReadOnlyMemory`1 )
at System.Net.Security.SslStream.WriteAsyncInternal[TIOAdapter](TIOAdapter , ReadOnlyMemory`1 )
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& )
at System.Net.Security.SslStream.WriteAsyncInternal[TIOAdapter](TIOAdapter , ReadOnlyMemory`1 )
at System.Net.Security.SslStream.WriteAsync(ReadOnlyMemory`1 , CancellationToken )
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(Boolean , ReadOnlyMemory`1 , CancellationToken )
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& )
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(Boolean , ReadOnlyMemory`1 , CancellationToken )
at System.IO.Pipelines.StreamPipeWriter.FlushAsync(CancellationToken )
at SmtpServer.IO.PipeWriterExtensions.WriteReplyAsync(PipeWriter writer, SmtpResponse response, CancellationToken cancellationToken)
at SmtpServer.Protocol.QuitCommand.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& )
at SmtpServer.Protocol.QuitCommand.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.ExecuteAsync(SmtpCommand command, SmtpSessionContext context, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& )
at SmtpServer.SmtpSession.ExecuteAsync(SmtpCommand command, SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox , Boolean )
at System.Threading.Tasks.Task.RunContinuations(Object )
at System.Threading.Tasks.Task`1.TrySetResult(TResult )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 , TResult )
at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1.SetResult(TResult )
at SmtpServer.SmtpSession.ReadCommandAsync(ISessionContext context, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox , Boolean )
at System.Threading.Tasks.Task.RunContinuations(Object )
at System.Threading.Tasks.Task`1.TrySetResult(TResult )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 , TResult )
at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder.SetResult()
at SmtpServer.IO.PipeReaderExtensions.ReadUntilAsync(PipeReader reader, Byte[] sequence, Func`2 func, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox , Boolean )
at System.Threading.Tasks.Task.RunContinuations(Object )
at System.Threading.Tasks.Task`1.TrySetResult(TResult )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 , TResult )
at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1.SetResult(TResult )
at System.IO.Pipelines.StreamPipeReader.<ReadAsync>g__Core|36_0(StreamPipeReader , CancellationTokenSource , CancellationToken )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox , Boolean )
at System.Threading.Tasks.Task.RunContinuations(Object )
at System.Threading.Tasks.Task`1.TrySetResult(TResult )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 , TResult )
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter , Memory`1 )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox , Boolean )
at System.Threading.Tasks.Task.RunContinuations(Object )
at System.Threading.Tasks.Task`1.TrySetResult(TResult )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 , TResult )
at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](TIOAdapter )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.ThreadPool.<>c.<.cctor>b__86_0(Object )
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.InvokeContinuation(Action`1 , Object , Boolean , Boolean )
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs )
at System.Net.Sockets.SocketAsyncEventArgs.OnCompletedInternal()
at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncSuccess(Int32 , SocketFlags )
at System.Net.Sockets.SocketAsyncEventArgs.CompletionCallback(Int32 , SocketFlags , SocketError )
at System.Net.Sockets.SocketAsyncEventArgs.TransferCompletionCallbackCore(Int32 , Byte[] , Int32 , SocketFlags , SocketError )
at System.Net.Sockets.SocketAsyncContext.BufferMemoryReceiveOperation.InvokeCallback(Boolean )
at System.Net.Sockets.SocketAsyncContext.OperationQueue`1.ProcessAsyncOperation(TOperation )
at System.Net.Sockets.SocketAsyncContext.ProcessAsyncReadOperation(ReadOperation )
at System.Net.Sockets.SocketAsyncContext.ReadOperation.System.Threading.IThreadPoolWorkItem.Execute()
at System.Net.Sockets.SocketAsyncContext.AsyncOperation.Process()
at System.Net.Sockets.SocketAsyncContext.HandleEvents(SocketEvents )
at System.Net.Sockets.SocketAsyncEngine.System.Threading.IThreadPoolWorkItem.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
--- End of stack trace from previous location ---
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.<WriteSingleChunk>g__CompleteWriteAsync|182_1[TIOAdapter](ValueTask , Byte[] )
at System.Net.Security.SslStream.WriteAsyncInternal[TIOAdapter](TIOAdapter , ReadOnlyMemory`1 )
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(Boolean , ReadOnlyMemory`1 , CancellationToken )
at SmtpServer.Protocol.QuitCommand.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.ExecuteAsync(SmtpCommand command, SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.RunAsync(CancellationToken cancellationToken)
at SmtpServer.SmtpSessionManager.RunAsync(SmtpSessionHandle handle, CancellationToken cancellationToken)
Unsecure
info: DockerMailReceiver.SmtpServerWorker[0]
SessionCreated - Port:25 IsSecure:False RemoteEndpoint:40.92.74.56
info: DockerMailReceiver.MailboxFilterFactories.DefaultMailboxFilterFactory[0]
DefaultMailboxFilterFactory - Port:25 IsSecure:False RemoteEndpoint:40.92.74.56
info: DockerMailReceiver.MailboxFilterFactories.DefaultMailboxFilterFactory[0]
DefaultMailboxFilterFactory - Port:25 IsSecure:False RemoteEndpoint:40.92.74.56
info: DockerMailReceiver.SmtpServerWorker[0]
SessionFaulted - System.IO.IOException: Unable to write data to the transport connection: Connection reset by peer.
---> System.Net.Sockets.SocketException (104): Connection reset by peer
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.CreateException(SocketError , Boolean )
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.SendAsyncForNetworkStream(Socket , CancellationToken )
at System.Net.Sockets.Socket.SendAsyncForNetworkStream(ReadOnlyMemory`1 , SocketFlags , CancellationToken )
at System.Net.Sockets.NetworkStream.WriteAsync(ReadOnlyMemory`1 , CancellationToken )
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(Boolean , ReadOnlyMemory`1 , CancellationToken )
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& )
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(Boolean , ReadOnlyMemory`1 , CancellationToken )
at System.IO.Pipelines.StreamPipeWriter.FlushAsync(CancellationToken )
at SmtpServer.IO.PipeWriterExtensions.WriteReplyAsync(PipeWriter writer, SmtpResponse response, CancellationToken cancellationToken)
at SmtpServer.Protocol.QuitCommand.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& )
at SmtpServer.Protocol.QuitCommand.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.ExecuteAsync(SmtpCommand command, SmtpSessionContext context, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& )
at SmtpServer.SmtpSession.ExecuteAsync(SmtpCommand command, SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox , Boolean )
at System.Threading.Tasks.Task.RunContinuations(Object )
at System.Threading.Tasks.Task.FinishContinuations()
at System.Threading.Tasks.Task`1.TrySetResult(TResult )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 , TResult )
at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1.SetResult(TResult )
at SmtpServer.SmtpSession.ReadCommandAsync(ISessionContext context, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox , Boolean )
at System.Threading.Tasks.Task.RunContinuations(Object )
at System.Threading.Tasks.Task.FinishContinuations()
at System.Threading.Tasks.Task`1.TrySetResult(TResult )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 , TResult )
at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder.SetResult()
at SmtpServer.IO.PipeReaderExtensions.ReadUntilAsync(PipeReader reader, Byte[] sequence, Func`2 func, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(IAsyncStateMachineBox , Boolean )
at System.Threading.Tasks.Task.RunContinuations(Object )
at System.Threading.Tasks.Task.FinishContinuations()
at System.Threading.Tasks.Task`1.TrySetResult(TResult )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 , TResult )
at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1.SetResult(TResult )
at System.IO.Pipelines.StreamPipeReader.<ReadAsync>g__Core|36_0(StreamPipeReader , CancellationTokenSource , CancellationToken )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object )
at System.Threading.ExecutionContext.RunInternal(ExecutionContext , ContextCallback , Object )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread )
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
at System.Threading.ThreadPool.<>c.<.cctor>b__86_0(Object )
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.InvokeContinuation(Action`1 , Object , Boolean , Boolean )
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs )
at System.Net.Sockets.SocketAsyncEventArgs.OnCompletedInternal()
at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncSuccess(Int32 , SocketFlags )
at System.Net.Sockets.SocketAsyncEventArgs.CompletionCallback(Int32 , SocketFlags , SocketError )
at System.Net.Sockets.SocketAsyncEventArgs.TransferCompletionCallbackCore(Int32 , Byte[] , Int32 , SocketFlags , SocketError )
at System.Net.Sockets.SocketAsyncContext.BufferMemoryReceiveOperation.InvokeCallback(Boolean )
at System.Net.Sockets.SocketAsyncContext.OperationQueue`1.ProcessAsyncOperation(TOperation )
at System.Net.Sockets.SocketAsyncContext.ProcessAsyncReadOperation(ReadOperation )
at System.Net.Sockets.SocketAsyncContext.ReadOperation.System.Threading.IThreadPoolWorkItem.Execute()
at System.Net.Sockets.SocketAsyncContext.AsyncOperation.Process()
at System.Net.Sockets.SocketAsyncContext.HandleEvents(SocketEvents )
at System.Net.Sockets.SocketAsyncEngine.System.Threading.IThreadPoolWorkItem.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
--- End of stack trace from previous location ---
--- End of inner exception stack trace ---
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(Boolean , ReadOnlyMemory`1 , CancellationToken )
at SmtpServer.Protocol.QuitCommand.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.ExecuteAsync(SmtpCommand command, SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken)
at SmtpServer.SmtpSession.RunAsync(CancellationToken cancellationToken)
at SmtpServer.SmtpSessionManager.RunAsync(SmtpSessionHandle handle, CancellationToken cancellationToken)
tcpdump
220 mail.testdomain.com v9.0.3.0 ESMTP ready
EHLO EUR03-DBA-obe.outbound.protection.outlook.com
250-mail.testdomain.com Hello EUR03-DBA-obe.outbound.protection.outlook.com, haven't we met before?
250-PIPELINING
250-8BITMIME
250 SMTPUTF8
MAIL FROM:<sender1@outlook.com> BODY=7BIT
RCPT TO:<test@testdomain.com>
DATA
250 Ok
250 Ok
354 end with <CRLF>.<CRLF>
XXXXXXXXXXXX
XXXXXXXXXXXX
.
250 Ok
QUIT
Today I had a little time to analyze the issue again. During further tests I saw that the error only happens at hotmail/outlook at gmx.at/gmail it works without problems.
I am having the same issue
I suspect that some mail servers arent following the protocol correctly.
The handshaking here should be as follows;
- Client sends the QUIT command
- Server receives QUIT and sends a 221 response
- Server disconnects
- Client waits for the 221 response and then disconnects
What seems to be happening is that some mail servers are likely just sending the QUIT command and then disconnecting. In theory theres nothing wrong with that, but it doesnt follow the spec.
I'm trying to confirm this is actually what is happening and then can figure out the best way to approach this.
Here's the catch in the spec;
The sender MUST NOT intentionally close the transmission channel until it sends a QUIT command, and it SHOULD wait until it receives the reply
So SHOULD means that it doesnt need to if there is a good reason not too. I suspect that they dont wait because it could improve the performance of their systems ever so sligthly.
I've published 10.0.0-beta1 for now which includes this change.
Hi,
This should now be fixed in v10.0.0 which is now published. Please re-raise if the issue is still occuring.
Please note that there is a breaking change to the mailbox filter API but its a very easy modification for implementations.