smtp transport: poll for trailing data to drain before close
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 25 Dec 2021 17:48:29 +0000 (17:48 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 25 Dec 2021 17:48:29 +0000 (17:48 +0000)
src/src/daemon.c
src/src/functions.h
src/src/transports/smtp.c

index b10974a7ab1c1ddcb7b45856a37aa54a96525f99..4a3cb6adbeea99b1bd5a957442bcc5f72ccff690 100644 (file)
@@ -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
index ba02b82b23132d443b4a7cbaa1e5b89d9e4367bd..efabef044b96ef5b7e305ec8a757d72e3700128e 100644 (file)
@@ -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)
 {
index ee07bcfe87dbd2155045c70c7d58559cac69443a..721056f278978bf5aa30b3471e53ff33d032e855 100644 (file)
@@ -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)