From 4369f1fa55517d676baa2cede28b96561fe6911d Mon Sep 17 00:00:00 2001 From: Aaron Jones Date: Fri, 16 Sep 2016 21:52:06 +0000 Subject: [PATCH] GNUTLS: Improve rb_ssl_connect_common() This is the same as the previous commit for rb_ssl_accept_common(). --- libratbox/src/gnutls.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/libratbox/src/gnutls.c b/libratbox/src/gnutls.c index f197e206..95f3a7bb 100644 --- a/libratbox/src/gnutls.c +++ b/libratbox/src/gnutls.c @@ -610,25 +610,43 @@ rb_ssl_tryconn_timeout_cb(rb_fde_t *const F, void *const data) static void rb_ssl_connect_common(rb_fde_t *const F, void *const data) { + lrb_assert(F != NULL); + lrb_assert(F->ssl != NULL); + errno = 0; int ret = gnutls_handshake(SSL_P(F)); + int err = errno; - if(ret == GNUTLS_E_AGAIN || (ret == GNUTLS_E_INTERRUPTED && (errno == 0 || rb_ignore_errno(errno)))) + if(ret == GNUTLS_E_AGAIN || (ret == GNUTLS_E_INTERRUPTED && (err == 0 || rb_ignore_errno(err)))) { unsigned int flags = (gnutls_record_get_direction(SSL_P(F)) == 0) ? RB_SELECT_READ : RB_SELECT_WRITE; rb_setselect(F, flags, rb_ssl_connect_common, data); return; } + // These 2 calls may affect errno, which is why we save it above and restore it below + rb_settimeout(F, 0, NULL, NULL); + rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL); + struct ssl_connect *const sconn = data; - F->ssl_errno = (unsigned long) -ret; - if(ret == GNUTLS_E_SUCCESS) + { + F->handshake_count++; rb_ssl_connect_realcb(F, RB_OK, sconn); + } + else if(err != 0) + { + errno = err; + rb_ssl_connect_realcb(F, RB_ERROR, sconn); + } else + { + errno = EIO; + F->ssl_errno = (unsigned long) -ret; rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn); + } } static void