From 4f228a1fc1569cb26c9ae7dde4a1b79ca25cb0ce Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 14 Nov 2010 19:52:18 -0500 Subject: [PATCH] Fix bug in bufferevent_connect on an openssl bufferevent that already had an fd The problem was that we were using openssl's BIO code's shutdown flag whenever BEV_OPT_CLOSE_ON_FREE was set. This made the BIO close the socket when it was freed... but it would be freed whenever we did a setfd on the bufferevent_openssl, even the no-op setfd in bufferevent_connect. So instead, we just set the shutdown flag to 0, and handle closing the fd ourselves. Spotted by Linus Nordberg --- bufferevent_openssl.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index e9a812d0..04dc31e2 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -1086,6 +1086,13 @@ be_openssl_destruct(struct bufferevent *bev) bufferevent_free(bev_ssl->underlying); bev_ssl->underlying = NULL; } + } else { + evutil_socket_t fd = -1; + BIO *bio = SSL_get_wbio(bev_ssl->ssl); + if (bio) + fd = BIO_get_fd(bio, NULL); + if (fd >= 0) + evutil_closesocket(fd); } SSL_free(bev_ssl->ssl); } else { @@ -1134,11 +1141,8 @@ be_openssl_ctrl(struct bufferevent *bev, if (bev_ssl->underlying) return -1; { - int flag = 0; BIO *bio; - if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) - flag = 1; - bio = BIO_new_socket(data->fd, flag); + bio = BIO_new_socket(data->fd, 0); SSL_set_bio(bev_ssl->ssl, bio, bio); bev_ssl->fd_is_set = 1; } @@ -1294,7 +1298,6 @@ bufferevent_openssl_socket_new(struct event_base *base, /* Does the SSL already have an fd? */ BIO *bio = SSL_get_wbio(ssl); long have_fd = -1; - const int shutdown_flag = !!(options & BEV_OPT_CLOSE_ON_FREE); if (bio) have_fd = BIO_get_fd(bio, NULL); @@ -1311,12 +1314,12 @@ bufferevent_openssl_socket_new(struct event_base *base, This is probably an error on our part. Fail. */ return NULL; } - (void) BIO_set_close(bio, shutdown_flag); + (void) BIO_set_close(bio, 0); } else { /* The SSL isn't configured with a BIO with an fd. */ if (fd >= 0) { /* ... and we have an fd we want to use. */ - bio = BIO_new_socket(fd, shutdown_flag); + bio = BIO_new_socket(fd, 0); SSL_set_bio(ssl, bio, bio); } else { /* Leave the fd unset. */ -- 2.50.0