SmtpServer
SmtpServer copied to clipboard
IOException replying to QUIT when receiving mail from outlook.com
It seems that outlook.com is not behaving very nicely when relaying mail, after it sends quit it looks like it is closing the connection before the response can be send, resulting in the exception below. This happens every time when receiving mail from Outlook. When mail is relayed/received from Gmail everything works as expected and if get "Command Executed" for QUIT followed by "SessionCompleted".
Is is possible to implement some checking when replying to QUIT if the connection is still active to prevent these exceptions?
SessionCreated: 40.107.22.44:8032 on port 25 Command Executing EHLO: DomainOrAddress=EUR05-AM6-obe.outbound.protection.outlook.com Command Executed EHLO: DomainOrAddress=EUR05-AM6-obe.outbound.protection.outlook.com Command Executing STARTTLS Command Executed STARTTLS Command Executing EHLO: DomainOrAddress=EUR05-AM6-obe.outbound.protection.outlook.com Command Executed EHLO: DomainOrAddress=EUR05-AM6-obe.outbound.protection.outlook.com Command Executing MAIL: Address=[REDACTED]@[REDACTED].[REDACTED] Parameters=SIZE=23964289,AUTH=<> Command Executed MAIL: Address=[REDACTED]@[REDACTED].[REDACTED] Parameters=SIZE=23964289,AUTH=<> Command Executing RCPT: Address=[REDACTED]@[REDACTED].[REDACTED] Command Executed RCPT: Address=[REDACTED]@[REDACTED].[REDACTED] Command Executing DATA Command Executed DATA Command Executing QUIT SessionFaulted: System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.. ---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host. --- End of inner exception stack trace --- at System.Net.Security.SslStream.<WriteSingleChunk>g__CompleteAsync|210_1[TWriteAdapter](ValueTask writeTask, Byte[] bufferToReturn) at System.Net.Security.SslStream.WriteAsyncInternal[TWriteAdapter](TWriteAdapter writeAdapter, ReadOnlyMemory`1 buffer) at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(CancellationToken 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)
I will look into this.
The specification is pretty clear that the client needs to wait for the response after initiating the QUIT command so I am surprised that Outlook would be doing it wrong, however, most servers are usually pretty lenient.
Yeah, it seems Microsoft is ignoring the specs. Thanks for looking into this! If you have something, I'll be happy to test it out!
I've published 10.0.0-beta1 for now which includes a fix to handle this.
Hi,
This should now be fixed in v10.0.0 which is now published.
Please note that there is a breaking change to the mailbox filter API but its a very easy modification for implementations.