summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2015-04-15 16:05:23 +0000
committerjsing <>2015-04-15 16:05:23 +0000
commitdcb31e966f316332772152f9dc4003581bf31395 (patch)
tree3d6921045d591206b78b5802a3cd741aa49ea5ef /src
parentf62c289c77e6f576e0fd3f26d631b4d0fe2cac1c (diff)
downloadopenbsd-dcb31e966f316332772152f9dc4003581bf31395.tar.gz
openbsd-dcb31e966f316332772152f9dc4003581bf31395.tar.bz2
openbsd-dcb31e966f316332772152f9dc4003581bf31395.zip
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 'src')
-rw-r--r--src/lib/libtls/tls.c30
1 files changed, 17 insertions, 13 deletions
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 @@
1/* $OpenBSD: tls.c,v 1.9 2015/04/02 13:19:15 jsing Exp $ */ 1/* $OpenBSD: tls.c,v 1.10 2015/04/15 16:05:23 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -327,30 +327,34 @@ int
327tls_close(struct tls *ctx) 327tls_close(struct tls *ctx)
328{ 328{
329 int ssl_ret; 329 int ssl_ret;
330 int rv = 0;
330 331
331 if (ctx->ssl_conn != NULL) { 332 if (ctx->ssl_conn != NULL) {
332 ssl_ret = SSL_shutdown(ctx->ssl_conn); 333 ssl_ret = SSL_shutdown(ctx->ssl_conn);
333 if (ssl_ret == 0) 334 if (ssl_ret < 0) {
334 ssl_ret = SSL_shutdown(ctx->ssl_conn); 335 rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret,
335 if (ssl_ret < 0)
336 return tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret,
337 "shutdown"); 336 "shutdown");
337 if (rv == TLS_READ_AGAIN || rv == TLS_WRITE_AGAIN)
338 return (rv);
339 }
338 } 340 }
339 341
340 if (ctx->socket != -1) { 342 if (ctx->socket != -1) {
341 if (shutdown(ctx->socket, SHUT_RDWR) != 0) { 343 if (shutdown(ctx->socket, SHUT_RDWR) != 0) {
342 tls_set_error(ctx, "shutdown"); 344 if (rv == 0 &&
343 goto err; 345 errno != ENOTCONN && errno != ECONNRESET) {
346 tls_set_error(ctx, "shutdown");
347 rv = -1;
348 }
344 } 349 }
345 if (close(ctx->socket) != 0) { 350 if (close(ctx->socket) != 0) {
346 tls_set_error(ctx, "close"); 351 if (rv == 0) {
347 goto err; 352 tls_set_error(ctx, "close");
353 rv = -1;
354 }
348 } 355 }
349 ctx->socket = -1; 356 ctx->socket = -1;
350 } 357 }
351 358
352 return (0); 359 return (rv);
353
354err:
355 return (-1);
356} 360}