crypto/aes/asm/aes-s390x.pl: fix $softonly=1 code path.
[openssl.git] / apps / s_socket.c
index b2bf244f23e38d7af59bc7a06697b43f34adbbb7..2f3e90bbf97a2eb07bb6d9ea6ac3ac2131243481 100644 (file)
@@ -28,10 +28,9 @@ typedef unsigned int u_int;
 
 #ifndef OPENSSL_NO_SOCK
 
-# define USE_SOCKETS
 # include "apps.h"
-# undef USE_SOCKETS
 # include "s_apps.h"
+# include "internal/sockets.h"
 
 # include <openssl/bio.h>
 # include <openssl/err.h>
@@ -215,13 +214,30 @@ int do_server(int *accept_sock, const char *host, const char *port,
         if (type == SOCK_STREAM) {
             do {
                 sock = BIO_accept_ex(asock, NULL, 0);
-            } while (sock < 0 && BIO_sock_should_retry(ret));
+            } while (sock < 0 && BIO_sock_should_retry(sock));
             if (sock < 0) {
                 ERR_print_errors(bio_err);
                 BIO_closesocket(asock);
                 break;
             }
             i = (*cb)(sock, type, protocol, context);
+            /*
+             * If we ended with an alert being sent, but still with data in the
+             * network buffer to be read, then calling BIO_closesocket() will
+             * result in a TCP-RST being sent. On some platforms (notably
+             * Windows) then this will result in the peer immediately abandoning
+             * the connection including any buffered alert data before it has
+             * had a chance to be read. Shutting down the sending side first,
+             * and then closing the socket sends TCP-FIN first followed by
+             * TCP-RST. This seems to allow the peer to read the alert data.
+             */
+#ifdef _WIN32
+# ifdef SD_SEND
+            shutdown(sock, SD_SEND);
+# endif
+#elif defined(SHUT_WR)
+            shutdown(sock, SHUT_WR);
+#endif
             BIO_closesocket(sock);
         } else {
             i = (*cb)(asock, type, protocol, context);