diff options
| author | jsing <> | 2015-04-15 16:05:23 +0000 |
|---|---|---|
| committer | jsing <> | 2015-04-15 16:05:23 +0000 |
| commit | 803fe901561ae85e774d8c387c4853742a37d03c (patch) | |
| tree | 3d6921045d591206b78b5802a3cd741aa49ea5ef /src/lib/libtls/tls.c | |
| parent | 48b163f0308a2df2e5a5b7f91edc2491e64089ba (diff) | |
| download | openbsd-803fe901561ae85e774d8c387c4853742a37d03c.tar.gz openbsd-803fe901561ae85e774d8c387c4853742a37d03c.tar.bz2 openbsd-803fe901561ae85e774d8c387c4853742a37d03c.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/lib/libtls/tls.c')
| -rw-r--r-- | src/lib/libtls/tls.c | 30 |
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 | |||
| 327 | tls_close(struct tls *ctx) | 327 | tls_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 | |||
| 354 | err: | ||
| 355 | return (-1); | ||
| 356 | } | 360 | } |
