From 6671c775e661b6bda139ec8154905bf566fb77c9 Mon Sep 17 00:00:00 2001
From: Andy Polyakov <appro@openssl.org>
Date: Sun, 20 May 2018 23:03:47 +0200
Subject: [PATCH] apps/s_socket.c: address rare TLSProxy failures on Windows.

Reviewed-by: Rich Salz <rsalz@openssl.org>
---
 apps/s_socket.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/apps/s_socket.c b/apps/s_socket.c
index d16108c706..f4264cd9ff 100644
--- a/apps/s_socket.c
+++ b/apps/s_socket.c
@@ -321,6 +321,10 @@ int do_server(int *accept_sock, const char *host, const char *port,
     if (accept_sock != NULL)
         *accept_sock = asock;
     for (;;) {
+        char sink[64];
+        struct timeval timeout;
+        fd_set readfds;
+
         if (type == SOCK_STREAM) {
             BIO_ADDR_free(ourpeer);
             ourpeer = BIO_ADDR_new();
@@ -351,6 +355,20 @@ int do_server(int *accept_sock, const char *host, const char *port,
              * TCP-RST. This seems to allow the peer to read the alert data.
              */
             shutdown(sock, 1); /* SHUT_WR */
+            /*
+             * We just said we have nothing else to say, but it doesn't mean
+             * that the other side has nothing. It's even recommended to
+             * consume incoming data. [In testing context this ensures that
+             * alerts are passed on...]
+             */
+            timeout.tv_sec = 0;
+            timeout.tv_usec = 500000;  /* some extreme round-trip */
+            do {
+                FD_ZERO(&readfds);
+                openssl_fdset(sock, &readfds);
+            } while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
+                     && readsocket(sock, sink, sizeof(sink)) > 0);
+
             BIO_closesocket(sock);
         } else {
             i = (*cb)(asock, type, protocol, context);
-- 
2.25.1