Add a testing-only option to use bufferevent_openssl as a filter

We need filtering bufferevent_openssl so that we can wrap around
IOCP bufferevents on Windows.  This patch adds a temporary option to
turn on filtering mode, so that we can test it out on non-IOCP
systems to make sure it hasn't got any surprising bugs.

It also fixes some allocation/teardown errors in using
bufferevent_openssl as a filter.
This commit is contained in:
Nick Mathewson 2010-11-09 15:36:27 -05:00
parent 1fb342dfab
commit d238d8386f
5 changed files with 42 additions and 29 deletions

View File

@ -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);

View File

@ -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

View File

@ -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"),

View File

@ -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;

View File

@ -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;