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.