From ef8a2428cfe2ba86715e8dc1f966f9532ff5d190 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 25 Dec 2021 17:48:29 +0000 Subject: [PATCH] smtp transport: poll for trailing data to drain before close --- src/src/daemon.c | 2 +- src/src/functions.h | 1 + src/src/transports/smtp.c | 7 +++++-- 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) -- 2.30.2