diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2015-04-15 16:05:24 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2015-04-15 16:05:24 +0000 |
commit | f5373ca74d503db5ee99c3648fad956832b038b7 (patch) | |
tree | f05c8d91c9a09a6f2530a93b52d6d558fdb9f132 /lib | |
parent | 66aa4e5feff68d520ab3c39a1a314b09ba5541a1 (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.c | 30 |
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); } |