diff options
-rw-r--r-- | src/common/tortls.c | 62 | ||||
-rw-r--r-- | src/common/tortls.h | 3 | ||||
-rw-r--r-- | src/or/config.c | 1 | ||||
-rw-r--r-- | src/or/connection_or.c | 3 | ||||
-rw-r--r-- | src/or/or.h | 2 |
5 files changed, 42 insertions, 29 deletions
diff --git a/src/common/tortls.c b/src/common/tortls.c index ba450e4b19..c4b25007b5 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -1826,41 +1826,49 @@ tor_tls_get_buffer_sizes(tor_tls_t *tls, */ struct bufferevent * tor_tls_init_bufferevent(tor_tls_t *tls, struct bufferevent *bufev_in, - evutil_socket_t socket, int receiving) + evutil_socket_t socket, int receiving, + int filter) { struct bufferevent *out; const enum bufferevent_ssl_state state = receiving ? BUFFEREVENT_SSL_ACCEPTING : BUFFEREVENT_SSL_CONNECTING; -#if 0 - (void) socket; - out = bufferevent_openssl_filter_new(tor_libevent_get_base(), - bufev_in, - tls->ssl, - state, - BEV_OPT_DEFER_CALLBACKS); -#else - if (bufev_in) { - evutil_socket_t s = bufferevent_getfd(bufev_in); - tor_assert(s == -1 || s == socket); - tor_assert(evbuffer_get_length(bufferevent_get_input(bufev_in)) == 0); - tor_assert(evbuffer_get_length(bufferevent_get_output(bufev_in)) == 0); - tor_assert(BIO_number_read(SSL_get_rbio(tls->ssl)) == 0); - tor_assert(BIO_number_written(SSL_get_rbio(tls->ssl)) == 0); - bufferevent_free(bufev_in); + if (filter) { + /* Grab an extra reference to the SSL, since BEV_OPT_CLOSE_ON_FREE + means that the SSL will get freed too. + + This increment makes our SSL usage not-threadsafe, BTW. We should + see if we're allowed to use CRYPTO_add from outside openssl. */ + tls->ssl->references += 1; + out = bufferevent_openssl_filter_new(tor_libevent_get_base(), + bufev_in, + tls->ssl, + state, + BEV_OPT_DEFER_CALLBACKS| + BEV_OPT_CLOSE_ON_FREE); + } else { + if (bufev_in) { + evutil_socket_t s = bufferevent_getfd(bufev_in); + tor_assert(s == -1 || s == socket); + tor_assert(evbuffer_get_length(bufferevent_get_input(bufev_in)) == 0); + tor_assert(evbuffer_get_length(bufferevent_get_output(bufev_in)) == 0); + tor_assert(BIO_number_read(SSL_get_rbio(tls->ssl)) == 0); + tor_assert(BIO_number_written(SSL_get_rbio(tls->ssl)) == 0); + bufferevent_free(bufev_in); + } + + /* Current versions (as of 2.0.x) of Libevent need to defer + * bufferevent_openssl callbacks, or else our callback functions will + * get called reentrantly, which is bad for us. + */ + out = bufferevent_openssl_socket_new(tor_libevent_get_base(), + socket, + tls->ssl, + state, + BEV_OPT_DEFER_CALLBACKS); } tls->state = TOR_TLS_ST_BUFFEREVENT; - /* Current versions (as of 2.0.7-rc) of Libevent need to defer - * bufferevent_openssl callbacks, or else our callback functions will - * get called reentrantly, which is bad for us. - */ - out = bufferevent_openssl_socket_new(tor_libevent_get_base(), - socket, - tls->ssl, - state, - BEV_OPT_DEFER_CALLBACKS); -#endif /* Unblock _after_ creating the bufferevent, since accept/connect tend to * clear flags. */ tor_tls_unblock_renegotiation(tls); diff --git a/src/common/tortls.h b/src/common/tortls.h index 50d14da52f..fe7cd6cecf 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -99,7 +99,8 @@ void tor_tls_log_one_error(tor_tls_t *tls, unsigned long err, int tor_tls_start_renegotiating(tor_tls_t *tls); struct bufferevent *tor_tls_init_bufferevent(tor_tls_t *tls, struct bufferevent *bufev_in, - evutil_socket_t socket, int receiving); + evutil_socket_t socket, int receiving, + int filter); #endif #endif diff --git a/src/or/config.c b/src/or/config.c index 6a4e2c464c..8d7da19861 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -389,6 +389,7 @@ static config_var_t _option_vars[] = { VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"), V(VirtualAddrNetwork, STRING, "127.192.0.0/10"), V(WarnPlaintextPorts, CSV, "23,109,110,143"), + V(_UseFilteringSSLBufferevents, BOOL, "0"), VAR("__ReloadTorrcOnSIGHUP", BOOL, ReloadTorrcOnSIGHUP, "1"), VAR("__AllDirActionsPrivate", BOOL, AllDirActionsPrivate, "0"), VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"), diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 467f7be904..5b8236291a 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -906,9 +906,10 @@ connection_tls_start_handshake(or_connection_t *conn, int receiving) } #ifdef USE_BUFFEREVENTS if (connection_type_uses_bufferevent(TO_CONN(conn))) { + const int filtering = get_options()->_UseFilteringSSLBufferevents; struct bufferevent *b = tor_tls_init_bufferevent(conn->tls, conn->_base.bufev, conn->_base.s, - receiving); + receiving, filtering); if (!b) { log_warn(LD_BUG,"tor_tls_init_bufferevent failed. Closing."); return -1; diff --git a/src/or/or.h b/src/or/or.h index 5498d933cc..4b3c5a5422 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2991,6 +2991,8 @@ typedef struct { /** If true, do not enable IOCP on windows with bufferevents, even if * we think we could. */ int DisableIOCP; + /** For testing only: will go away in 0.2.3.x. */ + int _UseFilteringSSLBufferevents; } or_options_t; |