summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2021-12-25 17:48:29 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2021-12-25 17:48:29 +0000
commitef8a2428cfe2ba86715e8dc1f966f9532ff5d190 (patch)
tree6103872129174135c0c81390145d2cb4f4479354
parentdae124ff1a33721637d0be99181a4783ee46e25f (diff)
smtp transport: poll for trailing data to drain before close
-rw-r--r--src/src/daemon.c2
-rw-r--r--src/src/functions.h1
-rw-r--r--src/src/transports/smtp.c7
3 files changed, 7 insertions, 3 deletions
diff --git a/src/src/daemon.c b/src/src/daemon.c
index b10974a7a..4a3cb6adb 100644
--- a/src/src/daemon.c
+++ b/src/src/daemon.c
@@ -87,7 +87,7 @@ sigchld_seen = TRUE;
}
-/* SIGTERM handler. Try to get the damon pid file removed
+/* SIGTERM handler. Try to get the daemon pid file removed
before exiting. */
static void
diff --git a/src/src/functions.h b/src/src/functions.h
index ba02b82b2..efabef044 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -1254,6 +1254,7 @@ child_open(uschar **argv, uschar **envp, int newumask, int *infdptr,
outfdptr, make_leader, purpose);
}
+/* Return 1 if fd is usable per pollbits, else 0 */
static inline int
poll_one_fd(int fd, short pollbits, int tmo_millisec)
{
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index ee07bcfe8..721056f27 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -4810,8 +4810,11 @@ if (sx->send_quit || tcw_done && !tcw)
sx->cctx.tls_ctx = NULL;
}
#endif
- millisleep(20);
- if (fcntl(sx->cctx.sock, F_SETFL, O_NONBLOCK) == 0)
+
+ /* Drain any trailing data from the socket before close, to avoid sending a RST */
+
+ if ( poll_one_fd(sx->cctx.sock, POLLIN, 20) != 0 /* 20ms */
+ && fcntl(sx->cctx.sock, F_SETFL, O_NONBLOCK) == 0)
for (int i = 16, n; /* drain socket */
(n = read(sx->cctx.sock, sx->inbuffer, sizeof(sx->inbuffer))) > 0 && i > 0;
i--) HDEBUG(D_transport|D_acl|D_v)