]> granicus.if.org Git - libevent/commitdiff
Fix bug in bufferevent_connect on an openssl bufferevent that already had an fd
authorNick Mathewson <nickm@torproject.org>
Mon, 15 Nov 2010 00:52:18 +0000 (19:52 -0500)
committerNick Mathewson <nickm@torproject.org>
Mon, 15 Nov 2010 00:54:52 +0000 (19:54 -0500)
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

index e9a812d047b2440426b0d5d5b1d665391cc67ef8..04dc31e2d25a0e1e393458d0b6107148fc65a3b4 100644 (file)
@@ -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. */