MailKit: SmtpClient DisconnectAsync may not exit with an improperly closed remote connection
Describe the bug
DisconnectAsync can block when packets to a previously functioning session are suddenly dropped. Despite many attempts, I’m unable to get a cancellation token to end the task by setting a timer with CancelAfter.
I have a process which terminates a client session as such:
var client = new SmtpClient ();
.... mail processing here...
// Send and close
await client.SendAsync(mimeMessage).ConfigureAwait(false);
await client.DisconnectAsync(true).ConfigureAwait(false);
Occasionally, this job will hang – typically always while connecting to an office365.com MTA. I’m unable to reproduce the behavior in production, and resorted to creating an artificial experience with packet filtering on a FreeBSD-based mail server. When dropping packets from the client just prior to the invocation of DisconnectAsync, my client session never ends. I attempted to rectify by passing a Cancellation Token to DisconnectAsync, but the connection continued to hang indefinitely. Calling instead Disconnect(true), it appears the session will close when the stream timeout is reached. (i.e. to whatever value I’ve set client.Timeout)
To Reproduce Steps to reproduce the behavior:
- Create a new SmtpClient connection to a remote mail server.
- Prior to calling
DisconnectAsync(), sleep for 10 seconds - While MailKit SMTP client process sleeps, use a firewall to drop packets from the client to the mail server.
- For my tests, I used the FreeBSD packet filtering abilities, but I could have used any intermediate firewall. e.g.
sudo ipfw add 1000 drop ip from me to <client IP address> src-port 25
- See session not close
Expected behavior Expected would be the session to close after the default 120 second timeout, or allow a cancellation token to abort the task.
Screenshots If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
- OS: MacOS Mojave
Additional context Add any other context about the problem here.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 38 (20 by maintainers)
Commits related to this issue
- Modified SmtpStream to drop the connection when cancellation is requested Fixes issue #827 — committed to jstedfast/MailKit by jstedfast 5 years ago
- Updated NetworkStream.Read/WriteAsync() to make use of timeouts Fixes the latest report in issue #827 — committed to jstedfast/MailKit by jstedfast 4 years ago
We are experiencing similiar issue: await smtpclient.SendAsync(message) does to return.
The application is:
There is not particular pattern when the issue will happen. The app sends 1000 mail per day and it could run for weeks without issue or the issue happens after a few days.
Any help is greatly appreciated.