aboutsummaryrefslogtreecommitdiff
path: root/bufferevent_openssl.c
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2017-08-10 12:30:25 -0700
committerJosh Gao <jmgao@google.com>2017-08-10 12:30:47 -0700
commit83a0c9c65a60a92d3ea5542596b3ba56db492c37 (patch)
tree64bb0c050c4db9ad9d721e05e3e199bfd02e60b0 /bufferevent_openssl.c
parentaf241a5c8c2cde0fab7d7d563276c1095b00e3b4 (diff)
downloadlibevent-83a0c9c65a60a92d3ea5542596b3ba56db492c37.tar.gz
Revert "Upgrade to 2.1.8-stable (2017-01-22)." and "Probably Mac build fix?"android-o-iot-preview-5o-iot-preview-5
This reverts commits 2a572d125a91a4aafd3ad8ce87259fc640fa0763 and af241a5c8c2cde0fab7d7d563276c1095b00e3b4, which break tombstoned. Bug: http://b/64543673 Test: manual + treehugger
Diffstat (limited to 'bufferevent_openssl.c')
-rw-r--r--bufferevent_openssl.c455
1 files changed, 204 insertions, 251 deletions
diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c
index da3963a..7582d9b 100644
--- a/bufferevent_openssl.c
+++ b/bufferevent_openssl.c
@@ -24,17 +24,11 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// Get rid of OSX 10.7 and greater deprecation warnings.
-#if defined(__APPLE__) && defined(__clang__)
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#endif
+#include <sys/types.h>
#include "event2/event-config.h"
-#include "evconfig-private.h"
-
-#include <sys/types.h>
-#ifdef EVENT__HAVE_SYS_TIME_H
+#ifdef _EVENT_HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
@@ -42,14 +36,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef EVENT__HAVE_STDARG_H
+#ifdef _EVENT_HAVE_STDARG_H
#include <stdarg.h>
#endif
-#ifdef EVENT__HAVE_UNISTD_H
+#ifdef _EVENT_HAVE_UNISTD_H
#include <unistd.h>
#endif
-#ifdef _WIN32
+#ifdef WIN32
#include <winsock2.h>
#endif
@@ -66,7 +60,6 @@
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
-#include "openssl-compat.h"
/*
* Define an OpenSSL bio that targets a bufferevent.
@@ -110,8 +103,10 @@ print_err(int val)
static int
bio_bufferevent_new(BIO *b)
{
- BIO_set_init(b, 0);
- BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
+ b->init = 0;
+ b->num = -1;
+ b->ptr = NULL; /* We'll be putting the bufferevent in this field.*/
+ b->flags = 0;
return 1;
}
@@ -121,10 +116,12 @@ bio_bufferevent_free(BIO *b)
{
if (!b)
return 0;
- if (BIO_get_shutdown(b)) {
- if (BIO_get_init(b) && BIO_get_data(b))
- bufferevent_free(BIO_get_data(b));
- BIO_free(b);
+ if (b->shutdown) {
+ if (b->init && b->ptr)
+ bufferevent_free(b->ptr);
+ b->init = 0;
+ b->flags = 0;
+ b->ptr = NULL;
}
return 1;
}
@@ -140,10 +137,10 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
if (!out)
return 0;
- if (!BIO_get_data(b))
+ if (!b->ptr)
return -1;
- input = bufferevent_get_input(BIO_get_data(b));
+ input = bufferevent_get_input(b->ptr);
if (evbuffer_get_length(input) == 0) {
/* If there's no data to read, say so. */
BIO_set_retry_read(b);
@@ -159,13 +156,13 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
static int
bio_bufferevent_write(BIO *b, const char *in, int inlen)
{
- struct bufferevent *bufev = BIO_get_data(b);
+ struct bufferevent *bufev = b->ptr;
struct evbuffer *output;
size_t outlen;
BIO_clear_retry_flags(b);
- if (!BIO_get_data(b))
+ if (!b->ptr)
return -1;
output = bufferevent_get_output(bufev);
@@ -191,15 +188,15 @@ bio_bufferevent_write(BIO *b, const char *in, int inlen)
static long
bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
{
- struct bufferevent *bufev = BIO_get_data(b);
+ struct bufferevent *bufev = b->ptr;
long ret = 1;
switch (cmd) {
case BIO_CTRL_GET_CLOSE:
- ret = BIO_get_shutdown(b);
+ ret = b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
- BIO_set_shutdown(b, (int)num);
+ b->shutdown = (int)num;
break;
case BIO_CTRL_PENDING:
ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
@@ -228,24 +225,23 @@ bio_bufferevent_puts(BIO *b, const char *s)
}
/* Method table for the bufferevent BIO */
-static BIO_METHOD *methods_bufferevent;
+static BIO_METHOD methods_bufferevent = {
+ BIO_TYPE_LIBEVENT, "bufferevent",
+ bio_bufferevent_write,
+ bio_bufferevent_read,
+ bio_bufferevent_puts,
+ NULL /* bio_bufferevent_gets */,
+ bio_bufferevent_ctrl,
+ bio_bufferevent_new,
+ bio_bufferevent_free,
+ NULL /* callback_ctrl */,
+};
/* Return the method table for the bufferevents BIO */
static BIO_METHOD *
BIO_s_bufferevent(void)
{
- if (methods_bufferevent == NULL) {
- methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
- if (methods_bufferevent == NULL)
- return NULL;
- BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
- BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
- BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
- BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
- BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
- BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
- }
- return methods_bufferevent;
+ return &methods_bufferevent;
}
/* Create a new BIO to wrap communication around a bufferevent. If close_flag
@@ -258,9 +254,9 @@ BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
return NULL;
if (!(result = BIO_new(BIO_s_bufferevent())))
return NULL;
- BIO_set_init(result, 1);
- BIO_set_data(result, bufferevent);
- BIO_set_shutdown(result, close_flag ? 1 : 0);
+ result->init = 1;
+ result->ptr = bufferevent;
+ result->shutdown = close_flag ? 1 : 0;
return result;
}
@@ -316,20 +312,19 @@ struct bufferevent_openssl {
unsigned read_blocked_on_write : 1;
/* When we next get data, we should say "write" instead of "read". */
unsigned write_blocked_on_read : 1;
- /* Treat TCP close before SSL close on SSL >= v3 as clean EOF. */
+ /* XXX */
unsigned allow_dirty_shutdown : 1;
+ /* XXXX */
+ unsigned fd_is_set : 1;
/* XXX */
unsigned n_errors : 2;
/* Are we currently connecting, accepting, or doing IO? */
unsigned state : 2;
- /* If we reset fd, we sould reset state too */
- unsigned old_state : 2;
};
static int be_openssl_enable(struct bufferevent *, short);
static int be_openssl_disable(struct bufferevent *, short);
-static void be_openssl_unlink(struct bufferevent *);
static void be_openssl_destruct(struct bufferevent *);
static int be_openssl_adj_timeouts(struct bufferevent *);
static int be_openssl_flush(struct bufferevent *bufev,
@@ -341,7 +336,6 @@ const struct bufferevent_ops bufferevent_ops_openssl = {
evutil_offsetof(struct bufferevent_openssl, bev.bev),
be_openssl_enable,
be_openssl_disable,
- be_openssl_unlink,
be_openssl_destruct,
be_openssl_adj_timeouts,
be_openssl_flush,
@@ -382,15 +376,15 @@ static int
start_reading(struct bufferevent_openssl *bev_ssl)
{
if (bev_ssl->underlying) {
- bufferevent_unsuspend_read_(bev_ssl->underlying,
+ bufferevent_unsuspend_read(bev_ssl->underlying,
BEV_SUSPEND_FILT_READ);
return 0;
} else {
struct bufferevent *bev = &bev_ssl->bev.bev;
int r;
- r = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
+ r = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
if (r == 0 && bev_ssl->read_blocked_on_write)
- r = bufferevent_add_event_(&bev->ev_write,
+ r = _bufferevent_add_event(&bev->ev_write,
&bev->timeout_write);
return r;
}
@@ -404,15 +398,12 @@ start_writing(struct bufferevent_openssl *bev_ssl)
{
int r = 0;
if (bev_ssl->underlying) {
- if (bev_ssl->write_blocked_on_read) {
- bufferevent_unsuspend_read_(bev_ssl->underlying,
- BEV_SUSPEND_FILT_READ);
- }
+ ;
} else {
struct bufferevent *bev = &bev_ssl->bev.bev;
- r = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
+ r = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
if (!r && bev_ssl->write_blocked_on_read)
- r = bufferevent_add_event_(&bev->ev_read,
+ r = _bufferevent_add_event(&bev->ev_read,
&bev->timeout_read);
}
return r;
@@ -424,7 +415,7 @@ stop_reading(struct bufferevent_openssl *bev_ssl)
if (bev_ssl->write_blocked_on_read)
return;
if (bev_ssl->underlying) {
- bufferevent_suspend_read_(bev_ssl->underlying,
+ bufferevent_suspend_read(bev_ssl->underlying,
BEV_SUSPEND_FILT_READ);
} else {
struct bufferevent *bev = &bev_ssl->bev.bev;
@@ -438,8 +429,7 @@ stop_writing(struct bufferevent_openssl *bev_ssl)
if (bev_ssl->read_blocked_on_write)
return;
if (bev_ssl->underlying) {
- bufferevent_unsuspend_read_(bev_ssl->underlying,
- BEV_SUSPEND_FILT_READ);
+ ;
} else {
struct bufferevent *bev = &bev_ssl->bev.bev;
event_del(&bev->ev_write);
@@ -492,7 +482,7 @@ clear_wbor(struct bufferevent_openssl *bev_ssl)
}
static void
-conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret)
+conn_closed(struct bufferevent_openssl *bev_ssl, int errcode, int ret)
{
int event = BEV_EVENT_ERROR;
int dirty_shutdown = 0;
@@ -508,7 +498,7 @@ conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret)
break;
case SSL_ERROR_SYSCALL:
/* IO error; possibly a dirty shutdown. */
- if ((ret == 0 || ret == -1) && ERR_peek_error() == 0)
+ if (ret == 0 && ERR_peek_error() == 0)
dirty_shutdown = 1;
break;
case SSL_ERROR_SSL:
@@ -538,20 +528,16 @@ conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret)
stop_reading(bev_ssl);
stop_writing(bev_ssl);
- /* when is BEV_EVENT_{READING|WRITING} */
- event = when | event;
- bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
+ _bufferevent_run_eventcb(&bev_ssl->bev.bev, event);
}
static void
init_bio_counts(struct bufferevent_openssl *bev_ssl)
{
- BIO *rbio, *wbio;
-
- wbio = SSL_get_wbio(bev_ssl->ssl);
- bev_ssl->counts.n_written = wbio ? BIO_number_written(wbio) : 0;
- rbio = SSL_get_rbio(bev_ssl->ssl);
- bev_ssl->counts.n_read = rbio ? BIO_number_read(rbio) : 0;
+ bev_ssl->counts.n_written =
+ BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
+ bev_ssl->counts.n_read =
+ BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
}
static inline void
@@ -563,9 +549,9 @@ decrement_buckets(struct bufferevent_openssl *bev_ssl)
unsigned long w = num_w - bev_ssl->counts.n_written;
unsigned long r = num_r - bev_ssl->counts.n_read;
if (w)
- bufferevent_decrement_write_buckets_(&bev_ssl->bev, w);
+ _bufferevent_decrement_write_buckets(&bev_ssl->bev, w);
if (r)
- bufferevent_decrement_read_buckets_(&bev_ssl->bev, r);
+ _bufferevent_decrement_read_buckets(&bev_ssl->bev, r);
bev_ssl->counts.n_written = num_w;
bev_ssl->counts.n_read = num_r;
}
@@ -588,7 +574,7 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
if (bev_ssl->bev.read_suspended)
return 0;
- atmost = bufferevent_get_read_max_(&bev_ssl->bev);
+ atmost = _bufferevent_get_read_max(&bev_ssl->bev);
if (n_to_read > atmost)
n_to_read = atmost;
@@ -599,7 +585,6 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
for (i=0; i<n; ++i) {
if (bev_ssl->bev.read_suspended)
break;
- ERR_clear_error();
r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
if (r>0) {
result |= OP_MADE_PROGRESS;
@@ -627,7 +612,7 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
return OP_ERR | result;
break;
default:
- conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
+ conn_closed(bev_ssl, err, r);
break;
}
result |= OP_BLOCKED;
@@ -658,7 +643,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
if (bev_ssl->last_write > 0)
atmost = bev_ssl->last_write;
else
- atmost = bufferevent_get_write_max_(&bev_ssl->bev);
+ atmost = _bufferevent_get_write_max(&bev_ssl->bev);
n = evbuffer_peek(output, atmost, NULL, space, 8);
if (n < 0)
@@ -676,7 +661,6 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
if (space[i].iov_len == 0)
continue;
- ERR_clear_error();
r = SSL_write(bev_ssl->ssl, space[i].iov_base,
space[i].iov_len);
if (r > 0) {
@@ -707,7 +691,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
bev_ssl->last_write = space[i].iov_len;
break;
default:
- conn_closed(bev_ssl, BEV_EVENT_WRITING, err, r);
+ conn_closed(bev_ssl, err, r);
bev_ssl->last_write = -1;
break;
}
@@ -720,7 +704,8 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
if (bev_ssl->underlying)
BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
- bufferevent_trigger_nolock_(bev, EV_WRITE, BEV_OPT_DEFER_CALLBACKS);
+ if (evbuffer_get_length(output) <= bev->wm_write.low)
+ _bufferevent_run_writecb(bev);
}
return result;
}
@@ -764,7 +749,7 @@ bytes_to_read(struct bufferevent_openssl *bev)
}
/* Respect the rate limit */
- limit = bufferevent_get_read_max_(&bev->bev);
+ limit = _bufferevent_get_read_max(&bev->bev);
if (result > limit) {
result = limit;
}
@@ -834,8 +819,11 @@ consider_reading(struct bufferevent_openssl *bev_ssl)
if (all_result_flags & OP_MADE_PROGRESS) {
struct bufferevent *bev = &bev_ssl->bev.bev;
+ struct evbuffer *input = bev->input;
- bufferevent_trigger_nolock_(bev, EV_READ, 0);
+ if (evbuffer_get_length(input) >= bev->wm_read.low) {
+ _bufferevent_run_readcb(bev);
+ }
}
if (!bev_ssl->underlying) {
@@ -859,8 +847,11 @@ consider_writing(struct bufferevent_openssl *bev_ssl)
r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */
if (r & OP_MADE_PROGRESS) {
struct bufferevent *bev = &bev_ssl->bev.bev;
+ struct evbuffer *input = bev->input;
- bufferevent_trigger_nolock_(bev, EV_READ, 0);
+ if (evbuffer_get_length(input) >= bev->wm_read.low) {
+ _bufferevent_run_readcb(bev);
+ }
}
if (r & (OP_ERR|OP_BLOCKED))
break;
@@ -932,47 +923,35 @@ be_openssl_eventcb(struct bufferevent *bev_base, short what, void *ctx)
eat it. */
}
if (event)
- bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
+ _bufferevent_run_eventcb(&bev_ssl->bev.bev, event);
}
static void
be_openssl_readeventcb(evutil_socket_t fd, short what, void *ptr)
{
struct bufferevent_openssl *bev_ssl = ptr;
- bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
+ _bufferevent_incref_and_lock(&bev_ssl->bev.bev);
if (what == EV_TIMEOUT) {
- bufferevent_run_eventcb_(&bev_ssl->bev.bev,
- BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0);
+ _bufferevent_run_eventcb(&bev_ssl->bev.bev,
+ BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
} else {
consider_reading(bev_ssl);
}
- bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
+ _bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
}
static void
be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr)
{
struct bufferevent_openssl *bev_ssl = ptr;
- bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
+ _bufferevent_incref_and_lock(&bev_ssl->bev.bev);
if (what == EV_TIMEOUT) {
- bufferevent_run_eventcb_(&bev_ssl->bev.bev,
- BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0);
+ _bufferevent_run_eventcb(&bev_ssl->bev.bev,
+ BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
} else {
consider_writing(bev_ssl);
}
- bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
-}
-
-static int
-be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, int fd)
-{
- if (!bev_ssl->underlying) {
- struct bufferevent *bev = &bev_ssl->bev.bev;
- if (event_initialized(&bev->ev_read) && fd < 0) {
- fd = event_get_fd(&bev->ev_read);
- }
- }
- return fd;
+ _bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
}
static int
@@ -986,27 +965,25 @@ set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
} else {
struct bufferevent *bev = &bev_ssl->bev.bev;
int rpending=0, wpending=0, r1=0, r2=0;
-
- if (event_initialized(&bev->ev_read)) {
+ if (fd < 0 && bev_ssl->fd_is_set)
+ fd = event_get_fd(&bev->ev_read);
+ if (bev_ssl->fd_is_set) {
rpending = event_pending(&bev->ev_read, EV_READ, NULL);
wpending = event_pending(&bev->ev_write, EV_WRITE, NULL);
-
event_del(&bev->ev_read);
event_del(&bev->ev_write);
}
-
event_assign(&bev->ev_read, bev->ev_base, fd,
- EV_READ|EV_PERSIST|EV_FINALIZE,
- be_openssl_readeventcb, bev_ssl);
+ EV_READ|EV_PERSIST, be_openssl_readeventcb, bev_ssl);
event_assign(&bev->ev_write, bev->ev_base, fd,
- EV_WRITE|EV_PERSIST|EV_FINALIZE,
- be_openssl_writeeventcb, bev_ssl);
-
+ EV_WRITE|EV_PERSIST, be_openssl_writeeventcb, bev_ssl);
if (rpending)
- r1 = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
+ r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
if (wpending)
- r2 = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
-
+ r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
+ if (fd >= 0) {
+ bev_ssl->fd_is_set = 1;
+ }
return (r1<0 || r2<0) ? -1 : 0;
}
}
@@ -1023,34 +1000,38 @@ do_handshake(struct bufferevent_openssl *bev_ssl)
return -1;
case BUFFEREVENT_SSL_CONNECTING:
case BUFFEREVENT_SSL_ACCEPTING:
- ERR_clear_error();
r = SSL_do_handshake(bev_ssl->ssl);
break;
}
decrement_buckets(bev_ssl);
if (r==1) {
- int fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
/* We're done! */
bev_ssl->state = BUFFEREVENT_SSL_OPEN;
- set_open_callbacks(bev_ssl, fd); /* XXXX handle failure */
+ set_open_callbacks(bev_ssl, -1); /* XXXX handle failure */
/* Call do_read and do_write as needed */
bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled);
- bufferevent_run_eventcb_(&bev_ssl->bev.bev,
- BEV_EVENT_CONNECTED, 0);
+ _bufferevent_run_eventcb(&bev_ssl->bev.bev,
+ BEV_EVENT_CONNECTED);
return 1;
} else {
int err = SSL_get_error(bev_ssl->ssl, r);
print_err(err);
switch (err) {
case SSL_ERROR_WANT_WRITE:
- stop_reading(bev_ssl);
- return start_writing(bev_ssl);
+ if (!bev_ssl->underlying) {
+ stop_reading(bev_ssl);
+ return start_writing(bev_ssl);
+ }
+ return 0;
case SSL_ERROR_WANT_READ:
- stop_writing(bev_ssl);
- return start_reading(bev_ssl);
+ if (!bev_ssl->underlying) {
+ stop_writing(bev_ssl);
+ return start_reading(bev_ssl);
+ }
+ return 0;
default:
- conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
+ conn_closed(bev_ssl, err, r);
return -1;
}
}
@@ -1068,12 +1049,12 @@ be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr)
{
struct bufferevent_openssl *bev_ssl = ptr;
- bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
+ _bufferevent_incref_and_lock(&bev_ssl->bev.bev);
if (what & EV_TIMEOUT) {
- bufferevent_run_eventcb_(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT, 0);
+ _bufferevent_run_eventcb(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT);
} else
do_handshake(bev_ssl);/* XXX handle failure */
- bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
+ _bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
}
static int
@@ -1084,31 +1065,26 @@ set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
be_openssl_handshakecb, be_openssl_handshakecb,
be_openssl_eventcb,
bev_ssl);
-
- if (fd < 0)
- return 0;
-
- if (bufferevent_setfd(bev_ssl->underlying, fd))
- return 1;
-
return do_handshake(bev_ssl);
} else {
struct bufferevent *bev = &bev_ssl->bev.bev;
-
- if (event_initialized(&bev->ev_read)) {
+ int r1=0, r2=0;
+ if (fd < 0 && bev_ssl->fd_is_set)
+ fd = event_get_fd(&bev->ev_read);
+ if (bev_ssl->fd_is_set) {
event_del(&bev->ev_read);
event_del(&bev->ev_write);
}
-
event_assign(&bev->ev_read, bev->ev_base, fd,
- EV_READ|EV_PERSIST|EV_FINALIZE,
- be_openssl_handshakeeventcb, bev_ssl);
+ EV_READ|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl);
event_assign(&bev->ev_write, bev->ev_base, fd,
- EV_WRITE|EV_PERSIST|EV_FINALIZE,
- be_openssl_handshakeeventcb, bev_ssl);
- if (fd >= 0)
- bufferevent_enable(bev, bev->enabled);
- return 0;
+ EV_WRITE|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl);
+ if (fd >= 0) {
+ r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
+ r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
+ bev_ssl->fd_is_set = 1;
+ }
+ return (r1<0 || r2<0) ? -1 : 0;
}
}
@@ -1121,7 +1097,7 @@ bufferevent_ssl_renegotiate(struct bufferevent *bev)
if (SSL_renegotiate(bev_ssl->ssl) < 0)
return -1;
bev_ssl->state = BUFFEREVENT_SSL_CONNECTING;
- if (set_handshake_callbacks(bev_ssl, be_openssl_auto_fd(bev_ssl, -1)) < 0)
+ if (set_handshake_callbacks(bev_ssl, -1) < 0)
return -1;
if (!bev_ssl->underlying)
return do_handshake(bev_ssl);
@@ -1138,14 +1114,12 @@ be_openssl_outbuf_cb(struct evbuffer *buf,
if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) {
if (cbinfo->orig_size == 0)
- r = bufferevent_add_event_(&bev_ssl->bev.bev.ev_write,
+ r = _bufferevent_add_event(&bev_ssl->bev.bev.ev_write,
&bev_ssl->bev.bev.timeout_write);
-
- if (bev_ssl->underlying)
- consider_writing(bev_ssl);
+ consider_writing(bev_ssl);
}
/* XXX Handle r < 0 */
- (void)r;
+ (void)r;
}
@@ -1155,6 +1129,9 @@ be_openssl_enable(struct bufferevent *bev, short events)
struct bufferevent_openssl *bev_ssl = upcast(bev);
int r1 = 0, r2 = 0;
+ if (bev_ssl->state != BUFFEREVENT_SSL_OPEN)
+ return 0;
+
if (events & EV_READ)
r1 = start_reading(bev_ssl);
if (events & EV_WRITE)
@@ -1178,6 +1155,8 @@ static int
be_openssl_disable(struct bufferevent *bev, short events)
{
struct bufferevent_openssl *bev_ssl = upcast(bev);
+ if (bev_ssl->state != BUFFEREVENT_SSL_OPEN)
+ return 0;
if (events & EV_READ)
stop_reading(bev_ssl);
@@ -1194,10 +1173,17 @@ be_openssl_disable(struct bufferevent *bev, short events)
}
static void
-be_openssl_unlink(struct bufferevent *bev)
+be_openssl_destruct(struct bufferevent *bev)
{
struct bufferevent_openssl *bev_ssl = upcast(bev);
+ if (bev_ssl->underlying) {
+ _bufferevent_del_generic_timeout_cbs(bev);
+ } else {
+ event_del(&bev->ev_read);
+ event_del(&bev->ev_write);
+ }
+
if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
if (bev_ssl->underlying) {
if (BEV_UPCAST(bev_ssl->underlying)->refcnt < 2) {
@@ -1205,29 +1191,9 @@ be_openssl_unlink(struct bufferevent *bev)
"bufferevent with too few references");
} else {
bufferevent_free(bev_ssl->underlying);
- /* We still have a reference to it, via our
- * BIO. So we don't drop this. */
- // bev_ssl->underlying = NULL;
+ bev_ssl->underlying = NULL;
}
- }
- } else {
- if (bev_ssl->underlying) {
- if (bev_ssl->underlying->errorcb == be_openssl_eventcb)
- bufferevent_setcb(bev_ssl->underlying,
- NULL,NULL,NULL,NULL);
- bufferevent_unsuspend_read_(bev_ssl->underlying,
- BEV_SUSPEND_FILT_READ);
- }
- }
-}
-
-static void
-be_openssl_destruct(struct bufferevent *bev)
-{
- struct bufferevent_openssl *bev_ssl = upcast(bev);
-
- if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
- if (! bev_ssl->underlying) {
+ } else {
evutil_socket_t fd = -1;
BIO *bio = SSL_get_wbio(bev_ssl->ssl);
if (bio)
@@ -1236,6 +1202,14 @@ be_openssl_destruct(struct bufferevent *bev)
evutil_closesocket(fd);
}
SSL_free(bev_ssl->ssl);
+ } else {
+ if (bev_ssl->underlying) {
+ if (bev_ssl->underlying->errorcb == be_openssl_eventcb)
+ bufferevent_setcb(bev_ssl->underlying,
+ NULL,NULL,NULL,NULL);
+ bufferevent_unsuspend_read(bev_ssl->underlying,
+ BEV_SUSPEND_FILT_READ);
+ }
}
}
@@ -1244,10 +1218,15 @@ be_openssl_adj_timeouts(struct bufferevent *bev)
{
struct bufferevent_openssl *bev_ssl = upcast(bev);
- if (bev_ssl->underlying) {
- return bufferevent_generic_adj_timeouts_(bev);
- } else {
- return bufferevent_generic_adj_existing_timeouts_(bev);
+ if (bev_ssl->underlying)
+ return _bufferevent_generic_adj_timeouts(bev);
+ else {
+ int r1=0, r2=0;
+ if (event_pending(&bev->ev_read, EV_READ, NULL))
+ r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
+ if (event_pending(&bev->ev_write, EV_WRITE, NULL))
+ r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
+ return (r1<0 || r2<0) ? -1 : 0;
}
}
@@ -1260,60 +1239,35 @@ be_openssl_flush(struct bufferevent *bufev,
}
static int
-be_openssl_set_fd(struct bufferevent_openssl *bev_ssl,
- enum bufferevent_ssl_state state, int fd)
-{
- bev_ssl->state = state;
-
- switch (state) {
- case BUFFEREVENT_SSL_ACCEPTING:
- SSL_set_accept_state(bev_ssl->ssl);
- if (set_handshake_callbacks(bev_ssl, fd) < 0)
- return -1;
- break;
- case BUFFEREVENT_SSL_CONNECTING:
- SSL_set_connect_state(bev_ssl->ssl);
- if (set_handshake_callbacks(bev_ssl, fd) < 0)
- return -1;
- break;
- case BUFFEREVENT_SSL_OPEN:
- if (set_open_callbacks(bev_ssl, fd) < 0)
- return -1;
- break;
- default:
- return -1;
- }
-
- return 0;
-}
-
-static int
be_openssl_ctrl(struct bufferevent *bev,
enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data)
{
struct bufferevent_openssl *bev_ssl = upcast(bev);
switch (op) {
case BEV_CTRL_SET_FD:
- if (!bev_ssl->underlying) {
+ if (bev_ssl->underlying)
+ return -1;
+ {
BIO *bio;
bio = BIO_new_socket(data->fd, 0);
SSL_set_bio(bev_ssl->ssl, bio, bio);
- } else {
- BIO *bio;
- if (!(bio = BIO_new_bufferevent(bev_ssl->underlying, 0)))
- return -1;
- SSL_set_bio(bev_ssl->ssl, bio, bio);
+ bev_ssl->fd_is_set = 1;
}
-
- return be_openssl_set_fd(bev_ssl, bev_ssl->old_state, data->fd);
- case BEV_CTRL_GET_FD:
- if (bev_ssl->underlying) {
- data->fd = event_get_fd(&bev_ssl->underlying->ev_read);
- } else {
- data->fd = event_get_fd(&bev->ev_read);
+ if (bev_ssl->state == BUFFEREVENT_SSL_OPEN)
+ return set_open_callbacks(bev_ssl, data->fd);
+ else {
+ return set_handshake_callbacks(bev_ssl, data->fd);
}
+ case BEV_CTRL_GET_FD:
+ if (bev_ssl->underlying)
+ return -1;
+ if (!bev_ssl->fd_is_set)
+ return -1;
+ data->fd = event_get_fd(&bev->ev_read);
return 0;
case BEV_CTRL_GET_UNDERLYING:
+ if (!bev_ssl->underlying)
+ return -1;
data->ptr = bev_ssl->underlying;
return 0;
case BEV_CTRL_CANCEL_ALL:
@@ -1351,7 +1305,7 @@ bufferevent_openssl_new_impl(struct event_base *base,
bev_p = &bev_ssl->bev;
- if (bufferevent_init_common_(bev_p, base,
+ if (bufferevent_init_common(bev_p, base,
&bufferevent_ops_openssl, tmp_options) < 0)
goto err;
@@ -1366,28 +1320,52 @@ bufferevent_openssl_new_impl(struct event_base *base,
be_openssl_outbuf_cb, bev_ssl);
if (options & BEV_OPT_THREADSAFE)
- bufferevent_enable_locking_(&bev_ssl->bev.bev, NULL);
+ bufferevent_enable_locking(&bev_ssl->bev.bev, NULL);
if (underlying) {
- bufferevent_init_generic_timeout_cbs_(&bev_ssl->bev.bev);
- bufferevent_incref_(underlying);
+ _bufferevent_init_generic_timeout_cbs(&bev_ssl->bev.bev);
+ bufferevent_incref(underlying);
}
- bev_ssl->old_state = state;
+ bev_ssl->state = state;
bev_ssl->last_write = -1;
init_bio_counts(bev_ssl);
- fd = be_openssl_auto_fd(bev_ssl, fd);
- if (be_openssl_set_fd(bev_ssl, state, fd))
+ switch (state) {
+ case BUFFEREVENT_SSL_ACCEPTING:
+ SSL_set_accept_state(bev_ssl->ssl);
+ if (set_handshake_callbacks(bev_ssl, fd) < 0)
+ goto err;
+ break;
+ case BUFFEREVENT_SSL_CONNECTING:
+ SSL_set_connect_state(bev_ssl->ssl);
+ if (set_handshake_callbacks(bev_ssl, fd) < 0)
+ goto err;
+ break;
+ case BUFFEREVENT_SSL_OPEN:
+ if (set_open_callbacks(bev_ssl, fd) < 0)
+ goto err;
+ break;
+ default:
goto err;
+ }
if (underlying) {
bufferevent_setwatermark(underlying, EV_READ, 0, 0);
bufferevent_enable(underlying, EV_READ|EV_WRITE);
if (state == BUFFEREVENT_SSL_OPEN)
- bufferevent_suspend_read_(underlying,
+ bufferevent_suspend_read(underlying,
BEV_SUSPEND_FILT_READ);
+ } else {
+ bev_ssl->bev.bev.enabled = EV_READ|EV_WRITE;
+ if (bev_ssl->fd_is_set) {
+ if (state != BUFFEREVENT_SSL_OPEN)
+ if (event_add(&bev_ssl->bev.bev.ev_read, NULL) < 0)
+ goto err;
+ if (event_add(&bev_ssl->bev.bev.ev_write, NULL) < 0)
+ goto err;
+ }
}
return &bev_ssl->bev.bev;
@@ -1461,31 +1439,6 @@ bufferevent_openssl_socket_new(struct event_base *base,
base, NULL, fd, ssl, state, options);
}
-int
-bufferevent_openssl_get_allow_dirty_shutdown(struct bufferevent *bev)
-{
- int allow_dirty_shutdown = -1;
- struct bufferevent_openssl *bev_ssl;
- BEV_LOCK(bev);
- bev_ssl = upcast(bev);
- if (bev_ssl)
- allow_dirty_shutdown = bev_ssl->allow_dirty_shutdown;
- BEV_UNLOCK(bev);
- return allow_dirty_shutdown;
-}
-
-void
-bufferevent_openssl_set_allow_dirty_shutdown(struct bufferevent *bev,
- int allow_dirty_shutdown)
-{
- struct bufferevent_openssl *bev_ssl;
- BEV_LOCK(bev);
- bev_ssl = upcast(bev);
- if (bev_ssl)
- bev_ssl->allow_dirty_shutdown = !!allow_dirty_shutdown;
- BEV_UNLOCK(bev);
-}
-
unsigned long
bufferevent_get_openssl_error(struct bufferevent *bev)
{