From dcb31e966f316332772152f9dc4003581bf31395 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Wed, 15 Apr 2015 16:05:23 +0000
Subject: Make tls_close() more robust - do not rely on a close notify being
 received from the other side and only return TLS_READ_AGAIN/TLS_WRITE_AGAIN
 if we failed to send a close notify on a non-blocking socket.

Otherwise be more forceful and always shutdown/close the socket regardless
of other failures. Also do not consider ENOTCONN or ECONNRESET to be a
shutdown failure, since there are various situations where this can occur.

ok doug@ guenther@
---
 src/lib/libtls/tls.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

(limited to 'src/lib')

diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c
index d942c35fec..002cccda5f 100644
--- a/src/lib/libtls/tls.c
+++ b/src/lib/libtls/tls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.c,v 1.9 2015/04/02 13:19:15 jsing Exp $ */
+/* $OpenBSD: tls.c,v 1.10 2015/04/15 16:05:23 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -327,30 +327,34 @@ int
 tls_close(struct tls *ctx)
 {
 	int ssl_ret;
+	int rv = 0;
 
 	if (ctx->ssl_conn != NULL) {
 		ssl_ret = SSL_shutdown(ctx->ssl_conn);
-		if (ssl_ret == 0)
-			ssl_ret = SSL_shutdown(ctx->ssl_conn);
-		if (ssl_ret < 0)
-			return tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret,
+		if (ssl_ret < 0) {
+			rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret,
 			    "shutdown");
+			if (rv == TLS_READ_AGAIN || rv == TLS_WRITE_AGAIN)
+				return (rv);
+		}
 	}
 
 	if (ctx->socket != -1) {
 		if (shutdown(ctx->socket, SHUT_RDWR) != 0) {
-			tls_set_error(ctx, "shutdown");
-			goto err;
+			if (rv == 0 &&
+			    errno != ENOTCONN && errno != ECONNRESET) {
+				tls_set_error(ctx, "shutdown");
+				rv = -1;
+			}
 		}
 		if (close(ctx->socket) != 0) {
-			tls_set_error(ctx, "close");
-			goto err;
+			if (rv == 0) {
+				tls_set_error(ctx, "close");
+				rv = -1;
+			}
 		}
 		ctx->socket = -1;
 	}
 
-	return (0);
-
-err:
-	return (-1);
+	return (rv);
 }
-- 
cgit v1.2.3-55-g6feb