[or-cvs] [tor/master] Add a testing-only option to use bufferevent_openssl as a filter

nickm at torproject.org nickm at torproject.org
Tue Nov 9 20:37:41 UTC 2010


Author: Nick Mathewson <nickm at torproject.org>
Date: Tue, 9 Nov 2010 15:36:27 -0500
Subject: Add a testing-only option to use bufferevent_openssl as a filter
Commit: d238d8386fd1b459fa8e31b63363c9bd58e321f9

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.
---
 src/common/tortls.c    |   62 +++++++++++++++++++++++++++---------------------
 src/common/tortls.h    |    3 +-
 src/or/config.c        |    1 +
 src/or/connection_or.c |    3 +-
 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 ba450e4..c4b2500 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 50d14da..fe7cd6c 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 6a4e2c4..8d7da19 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 467f7be..5b82362 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 5498d93..4b3c5a5 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;
 
-- 
1.7.1



More information about the tor-commits mailing list