From 4d89c83c324605ba9945db238d82e0c1d33334a2 Mon Sep 17 00:00:00 2001 From: Aaron Jones Date: Fri, 16 Sep 2016 11:54:04 +0000 Subject: [PATCH] GNUTLS: Shut down sessions properly If gnutls_bye() fails with a fatal error, we would reattempt it again and again, even though this may then go on to e.g. cause a segmentation fault. Now we just keep retrying if it was interrupted, in line with the other backends, up to a maximum of 3 retries. --- libratbox/src/gnutls.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libratbox/src/gnutls.c b/libratbox/src/gnutls.c index 05fe8128..cb983eb6 100644 --- a/libratbox/src/gnutls.c +++ b/libratbox/src/gnutls.c @@ -58,18 +58,23 @@ static int cert_callback(gnutls_session_t session, const gnutls_datum_t *req_ca_ #define SSL_P(x) *((gnutls_session_t *)F->ssl) void -rb_ssl_shutdown(rb_fde_t *F) +rb_ssl_shutdown(rb_fde_t *const F) { - int i; if(F == NULL || F->ssl == NULL) return; - for(i = 0; i < 4; i++) + + for(int i = 0; i < 4; i++) { - if(gnutls_bye(SSL_P(F), GNUTLS_SHUT_RDWR) == GNUTLS_E_SUCCESS) + int ret = gnutls_bye(SSL_P(F), GNUTLS_SHUT_RDWR); + + if(ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_AGAIN) break; } + gnutls_deinit(SSL_P(F)); + rb_free(F->ssl); + F->ssl = NULL; } unsigned int