SmtpServer icon indicating copy to clipboard operation
SmtpServer copied to clipboard

No Timeout after DATA

Open tinohager opened this issue 1 year ago • 2 comments

When the session reaches the DATA part it can stay open forever there is no timeout that would close the session here. This allows the connection to remain open forever. I think it would make sense to be able to define an overall timeout for a session.

I think if we create a LinkedTokenSource in the SmtpSession with a timeout we could easily solve the problem. https://github.com/cosullivan/SmtpServer/blob/9d253c479e0f402d6cf2a002fb5815fad0b87a3a/Src/SmtpServer/SmtpSession.cs#L57

tinohager avatar Aug 27 '24 08:08 tinohager

I want to vote for this issue. We've just recently had a problem which went down to this. On the given day, Microsoft seemed to have a problem in it's SMTP transport. On a percentage of the connections, after the DATA command, no data was sent. The connections stayed open infinitely which resulted in many open connections on our side (which uses SmtpServer).

We tackled it in ReadUntilAsync of PipeReaderExtensions, by adding a LinkedTokenSource.

I further want to add some of my findings to clarify why the problem arises.

On creation of the duplex pipe in EndpointListener https://github.com/cosullivan/SmtpServer/blob/9d253c479e0f402d6cf2a002fb5815fad0b87a3a/Src/SmtpServer/Net/EndpointListener.cs#L46

the ReadTimeout is set, which is meant to set "The timeout on each individual buffer read".

https://github.com/cosullivan/SmtpServer/blob/9d253c479e0f402d6cf2a002fb5815fad0b87a3a/Src/SmtpServer/IEndpointDefinition.cs#L33

The thing is, that ReadTimeout of the underlying NetworkStream does not affect ReadAsync which is being used by SmtpServer. It only affects synchronous reads.

From the MS docs:

This property affects only synchronous reads performed by calling the Read method. This property does not affect asynchronous reads performed by calling the BeginRead or ReadAsync method.

I assume the ReadTimeout property of the IEndpointDefinition was supposed to handle this. But it does not, due to the nature of async reads.

It could be a solution to use the ReadTimeout of IEndpointDefinition to create a LinkedTokenSource and pass it on to the ReadAsync, down in ReadUntilAsync of PipeReaderExtensions. But, possibly there are other places too, which I have not yet found, so therefore, SmtpSession seems to be a better place, as suggested by @tinohager.

There is a pull request (#213) from @boba2fett which addresses this, in this commit https://github.com/cosullivan/SmtpServer/pull/213/commits/f51e1fcdfdfda3ddad399f05edfde9b741560e6c.

Let me know if, and how, I can support on this.

martinguenther avatar Aug 28 '24 12:08 martinguenther

fixed with 11.0.0-beta1

tinohager avatar Sep 24 '24 14:09 tinohager

Sounds like this should have been closed as it was implemented.

lostmsu avatar May 30 '25 05:05 lostmsu

Yes with v11

tinohager avatar May 30 '25 06:05 tinohager