summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2015-04-15 16:05:24 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2015-04-15 16:05:24 +0000
commitf5373ca74d503db5ee99c3648fad956832b038b7 (patch)
treef05c8d91c9a09a6f2530a93b52d6d558fdb9f132 /lib
parent66aa4e5feff68d520ab3c39a1a314b09ba5541a1 (diff)
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@
Diffstat (limited to 'lib')
-rw-r--r--lib/libtls/tls.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/lib/libtls/tls.c b/lib/libtls/tls.c
index d942c35fecf..002cccda5f6 100644
--- a/lib/libtls/tls.c
+++ b/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);
}