[or-cvs] [tor/master 03/38] Refactor users of buf_datalen to bufferevent-friendly version.

nickm at torproject.org nickm at torproject.org
Mon Sep 27 20:50:58 UTC 2010


Author: Nick Mathewson <nickm at torproject.org>
Date: Fri, 31 Jul 2009 11:39:31 -0400
Subject: Refactor users of buf_datalen to bufferevent-friendly version.
Commit: 200921dc313c7077c5d36aeda4b885e18c29fa70

---
 src/or/connection.c      |    7 ++-----
 src/or/connection.h      |   28 ++++++++++++++++++++++++++++
 src/or/connection_edge.c |    2 +-
 src/or/connection_or.c   |    8 ++++----
 src/or/cpuworker.c       |    2 +-
 src/or/directory.c       |    2 +-
 src/or/dirserv.c         |    8 ++++----
 src/or/main.c            |   21 +++++++++++----------
 src/or/or.h              |   44 +++++++++++++++++++++++++++++++++++++++-----
 src/or/relay.c           |    6 +++---
 10 files changed, 94 insertions(+), 34 deletions(-)

diff --git a/src/or/connection.c b/src/or/connection.c
index 6e3f8e6..cf3e9f3 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -36,10 +36,6 @@
 #include "router.h"
 #include "routerparse.h"
 
-#ifdef USE_BUFFEREVENTS
-#include <event2/bufferevent.h>
-#endif
-
 static connection_t *connection_create_listener(
                                struct sockaddr *listensockaddr,
                                socklen_t listensocklen, int type,
@@ -381,7 +377,8 @@ _connection_free(connection_t *conn)
              "bytes on inbuf, %d on outbuf.",
              conn_type_to_string(conn->type),
              conn_state_to_string(conn->type, conn->state),
-             (int)buf_datalen(conn->inbuf), (int)buf_datalen(conn->outbuf));
+             (int)connection_get_inbuf_len(conn),
+             (int)connection_get_outbuf_len(conn));
   }
 
   if (!connection_is_listener(conn)) {
diff --git a/src/or/connection.h b/src/or/connection.h
index f38927e..563b48c 100644
--- a/src/or/connection.h
+++ b/src/or/connection.h
@@ -12,6 +12,11 @@
 #ifndef _TOR_CONNECTION_H
 #define _TOR_CONNECTION_H
 
+#ifndef USE_BUFFEREVENTS
+/* XXXX For buf_datalen in inline function */
+#include "buffers.h"
+#endif
+
 const char *conn_type_to_string(int type);
 const char *conn_state_to_string(int type, int state);
 
@@ -73,6 +78,29 @@ connection_write_to_buf_zlib(const char *string, size_t len,
   _connection_write_to_buf_impl(string, len, TO_CONN(conn), done ? -1 : 1);
 }
 
+static size_t connection_get_inbuf_len(connection_t *conn);
+static size_t connection_get_outbuf_len(connection_t *conn);
+
+static INLINE size_t
+connection_get_inbuf_len(connection_t *conn)
+{
+  IF_HAS_BUFFEREVENT(conn, {
+    return evbuffer_get_length(bufferevent_get_input(conn->bufev));
+  }) ELSE_IF_NO_BUFFEREVENT {
+    return buf_datalen(conn->inbuf);
+  }
+}
+
+static INLINE size_t
+connection_get_outbuf_len(connection_t *conn)
+{
+  IF_HAS_BUFFEREVENT(conn, {
+    return evbuffer_get_length(bufferevent_get_output(conn->bufev));
+  }) ELSE_IF_NO_BUFFEREVENT {
+    return buf_datalen(conn->outbuf);
+  }
+}
+
 connection_t *connection_get_by_global_id(uint64_t id);
 
 connection_t *connection_get_by_type(int type);
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 6a3a5ef..c72d1b9 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -100,7 +100,7 @@ _connection_mark_unattached_ap(edge_connection_t *conn, int endreason,
 int
 connection_edge_reached_eof(edge_connection_t *conn)
 {
-  if (buf_datalen(conn->_base.inbuf) &&
+  if (connection_get_inbuf_len(TO_CONN(conn)) &&
       connection_state_is_open(TO_CONN(conn))) {
     /* it still has stuff to process. don't let it die yet. */
     return 0;
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 6b648b1..cb2c429 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -248,7 +248,7 @@ connection_or_process_inbuf(or_connection_t *conn)
 int
 connection_or_flushed_some(or_connection_t *conn)
 {
-  size_t datalen = buf_datalen(conn->_base.outbuf);
+  size_t datalen = connection_get_outbuf_len(TO_CONN(conn));
   /* If we're under the low water mark, add cells until we're just over the
    * high water mark. */
   if (datalen < OR_CONN_LOWWATER) {
@@ -1277,7 +1277,7 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
   while (1) {
     log_debug(LD_OR,
               "%d: starting, inbuf_datalen %d (%d pending in tls object).",
-              conn->_base.s,(int)buf_datalen(conn->_base.inbuf),
+              conn->_base.s,(int)connection_get_inbuf_len(TO_CONN(conn)),
               tor_tls_get_pending_bytes(conn->tls));
     if (connection_fetch_var_cell_from_buf(conn, &var_cell)) {
       if (!var_cell)
@@ -1288,8 +1288,8 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
     } else {
       char buf[CELL_NETWORK_SIZE];
       cell_t cell;
-      if (buf_datalen(conn->_base.inbuf) < CELL_NETWORK_SIZE) /* whole response
-                                                                 available? */
+      if (connection_get_inbuf_len(TO_CONN(conn))
+          < CELL_NETWORK_SIZE) /* whole response available? */
         return 0; /* not yet */
 
       circuit_build_times_network_is_live(&circ_times);
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 6f943d7..07a1c2f 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -141,7 +141,7 @@ connection_cpu_process_inbuf(connection_t *conn)
   tor_assert(conn);
   tor_assert(conn->type == CONN_TYPE_CPUWORKER);
 
-  if (!buf_datalen(conn->inbuf))
+  if (!connection_get_inbuf_len(conn))
     return 0;
 
   if (conn->state == CPUWORKER_STATE_BUSY_ONION) {
diff --git a/src/or/directory.c b/src/or/directory.c
index b109cb5..7f8d116 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2134,7 +2134,7 @@ connection_dir_process_inbuf(dir_connection_t *conn)
     return 0;
   }
 
-  if (buf_datalen(conn->_base.inbuf) > MAX_DIRECTORY_OBJECT_SIZE) {
+  if (connection_get_inbuf_len(TO_CONN(conn)) > MAX_DIRECTORY_OBJECT_SIZE) {
     log_warn(LD_HTTP, "Too much data received from directory connection: "
              "denial of service attempt, or you need to upgrade?");
     connection_mark_for_close(TO_CONN(conn));
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 3fcf178..397b1c1 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -3389,7 +3389,7 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
   time_t publish_cutoff = time(NULL)-ROUTER_MAX_AGE_TO_PUBLISH;
 
   while (smartlist_len(conn->fingerprint_stack) &&
-         buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
+         connection_get_outbuf_len(TO_CONN(conn)) < DIRSERV_BUFFER_MIN) {
     const char *body;
     char *fp = smartlist_pop_last(conn->fingerprint_stack);
     signed_descriptor_t *sd = NULL;
@@ -3489,7 +3489,7 @@ connection_dirserv_add_dir_bytes_to_outbuf(dir_connection_t *conn)
   ssize_t bytes;
   int64_t remaining;
 
-  bytes = DIRSERV_BUFFER_MIN - buf_datalen(conn->_base.outbuf);
+  bytes = DIRSERV_BUFFER_MIN - connection_get_outbuf_len(TO_CONN(conn));
   tor_assert(bytes > 0);
   tor_assert(conn->cached_dir);
   if (bytes < 8192)
@@ -3528,7 +3528,7 @@ static int
 connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn)
 {
 
-  while (buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
+  while (connection_get_outbuf_len(TO_CONN(conn)) < DIRSERV_BUFFER_MIN) {
     if (conn->cached_dir) {
       int uncompressing = (conn->zlib_state != NULL);
       int r = connection_dirserv_add_dir_bytes_to_outbuf(conn);
@@ -3574,7 +3574,7 @@ connection_dirserv_flushed_some(dir_connection_t *conn)
 {
   tor_assert(conn->_base.state == DIR_CONN_STATE_SERVER_WRITING);
 
-  if (buf_datalen(conn->_base.outbuf) >= DIRSERV_BUFFER_MIN)
+  if (connection_get_outbuf_len(TO_CONN(conn)) >= DIRSERV_BUFFER_MIN)
     return 0;
 
   switch (conn->dir_spool_src) {
diff --git a/src/or/main.c b/src/or/main.c
index a9dfecb..54c78c3 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -662,8 +662,8 @@ conn_close_if_marked(int i)
       }
       log_debug(LD_GENERAL, "Flushed last %d bytes from a linked conn; "
                "%d left; flushlen %d; wants-to-flush==%d", retval,
-               (int)buf_datalen(conn->outbuf),
-               (int)conn->outbuf_flushlen,
+                (int)connection_get_outbuf_len(conn),
+                (int)conn->outbuf_flushlen,
                 connection_wants_to_flush(conn));
     } else if (connection_speaks_cells(conn)) {
       if (conn->state == OR_CONN_STATE_OPEN) {
@@ -700,7 +700,7 @@ conn_close_if_marked(int i)
              "something is wrong with your network connection, or "
              "something is wrong with theirs. "
              "(fd %d, type %s, state %d, marked at %s:%d).",
-             (int)buf_datalen(conn->outbuf),
+             (int)connection_get_outbuf_len(conn),
              escaped_safe_str_client(conn->address),
              conn->s, conn_type_to_string(conn->type), conn->state,
              conn->marked_for_close_file,
@@ -793,7 +793,8 @@ run_connection_housekeeping(int i, time_t now)
   int past_keepalive =
     now >= conn->timestamp_lastwritten + options->KeepalivePeriod;
 
-  if (conn->outbuf && !buf_datalen(conn->outbuf) && conn->type == CONN_TYPE_OR)
+  if (conn->outbuf && !connection_get_outbuf_len(conn) &&
+      conn->type == CONN_TYPE_OR)
     TO_OR_CONN(conn)->timestamp_lastempty = now;
 
   if (conn->marked_for_close) {
@@ -813,7 +814,7 @@ run_connection_housekeeping(int i, time_t now)
     /* This check is temporary; it's to let us know whether we should consider
      * parsing partial serverdesc responses. */
     if (conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC &&
-        buf_datalen(conn->inbuf)>=1024) {
+        connection_get_inbuf_len(conn) >= 1024) {
       log_info(LD_DIR,"Trying to extract information from wedged server desc "
                "download.");
       connection_dir_reached_eof(TO_DIR_CONN(conn));
@@ -852,7 +853,7 @@ run_connection_housekeeping(int i, time_t now)
       connection_mark_for_close(conn);
     }
   } else if (we_are_hibernating() && !or_conn->n_circuits &&
-             !buf_datalen(conn->outbuf)) {
+             !connection_get_outbuf_len(conn)) {
     /* We're hibernating, there's no circuits, and nothing to flush.*/
     log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
              "[Hibernating or exiting].",
@@ -874,10 +875,10 @@ run_connection_housekeeping(int i, time_t now)
            "Expiring stuck OR connection to fd %d (%s:%d). (%d bytes to "
            "flush; %d seconds since last write)",
            conn->s, conn->address, conn->port,
-           (int)buf_datalen(conn->outbuf),
+           (int)connection_get_outbuf_len(conn),
            (int)(now-conn->timestamp_lastwritten));
     connection_mark_for_close(conn);
-  } else if (past_keepalive && !buf_datalen(conn->outbuf)) {
+  } else if (past_keepalive && !connection_get_outbuf_len(conn)) {
     /* send a padding cell */
     log_fn(LOG_DEBUG,LD_OR,"Sending keepalive to (%s:%d)",
            conn->address, conn->port);
@@ -1768,13 +1769,13 @@ dumpstats(int severity)
       log(severity,LD_GENERAL,
           "Conn %d: %d bytes waiting on inbuf (len %d, last read %d secs ago)",
           i,
-          (int)buf_datalen(conn->inbuf),
+          (int)connection_get_inbuf_len(conn),
           (int)buf_allocation(conn->inbuf),
           (int)(now - conn->timestamp_lastread));
       log(severity,LD_GENERAL,
           "Conn %d: %d bytes waiting on outbuf "
           "(len %d, last written %d secs ago)",i,
-          (int)buf_datalen(conn->outbuf),
+          (int)connection_get_outbuf_len(conn),
           (int)buf_allocation(conn->outbuf),
           (int)(now - conn->timestamp_lastwritten));
       if (conn->type == CONN_TYPE_OR) {
diff --git a/src/or/or.h b/src/or/or.h
index a699685..0246da8 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -83,6 +83,12 @@
 #define snprintf _snprintf
 #endif
 
+#ifdef USE_BUFFEREVENTS
+#include <event2/bufferevent.h>
+#include <event2/buffer.h>
+#endif
+
+#include "crypto.h"
 #include "tortls.h"
 #include "../common/torlog.h"
 #include "container.h"
@@ -1270,17 +1276,45 @@ static INLINE control_connection_t *TO_CONTROL_CONN(connection_t *c)
   return DOWNCAST(control_connection_t, c);
 }
 
+/* Conditional macros to help write code that works whether bufferevents are
+   disabled or not.
+
+   We can't just write:
+      if (conn->bufev) {
+        do bufferevent stuff;
+      } else {
+        do other stuff;
+      }
+   because the bufferevent stuff won't even compile unless we have a fairly
+   new version of Libevent.  Instead, we say:
+      IF_HAS_BUFFEREVENT(conn, { do_bufferevent_stuff } );
+   or:
+      IF_HAS_BUFFEREVENT(conn, {
+        do bufferevent stuff;
+      }) ELSE_IF_NO_BUFFEREVENT {
+        do non-bufferevent stuff;
+      }
+   If we're compiling with bufferevent support, then the macros expand more or
+   less to:
+      if (conn->bufev) {
+        do_bufferevent_stuff;
+      } else {
+        do non-bufferevent stuff;
+      }
+   and if we aren't using bufferevents, they expand more or less to:
+      { do non-bufferevent stuff; }
+*/
 #ifdef USE_BUFFEREVENTS
 #define HAS_BUFFEREVENT(c) (((c)->bufev) != NULL)
-#define IF_HAS_BUFFEREVENT(c, stmt)               \
-  do {                                               \
-    if ((conn)->bufev) do {                          \
-        stmt ;                                       \
-      } while(0);                                    \
+#define IF_HAS_BUFFEREVENT(c, stmt)                \
+  if ((c)->bufev) do {                             \
+      stmt ;                                       \
   } while (0)
+#define ELSE_IF_NO_BUFFEREVENT ; else
 #else
 #define HAS_BUFFEREVENT(c) (0)
 #define IF_HAS_BUFFEREVENT(c, stmt) (void)0
+#define ELSE_IF_NO_BUFFEREVENT ;
 #endif
 
 /** What action type does an address policy indicate: accept or reject? */
diff --git a/src/or/relay.c b/src/or/relay.c
index 480a291..16048fa 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1365,7 +1365,7 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
     return 0;
   }
 
-  amount_to_process = buf_datalen(conn->_base.inbuf);
+  amount_to_process = connection_get_inbuf_len(TO_CONN(conn));
 
   if (!amount_to_process)
     return 0;
@@ -1384,7 +1384,7 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
   connection_fetch_from_buf(payload, length, TO_CONN(conn));
 
   log_debug(domain,"(%d) Packaging %d bytes (%d waiting).", conn->_base.s,
-            (int)length, (int)buf_datalen(conn->_base.inbuf));
+            (int)length, (int)connection_get_inbuf_len(TO_CONN(conn)));
 
   if (connection_edge_send_command(conn, RELAY_COMMAND_DATA,
                                    payload, length) < 0 )
@@ -2415,7 +2415,7 @@ append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
     make_circuit_active_on_conn(circ, orconn);
   }
 
-  if (! buf_datalen(orconn->_base.outbuf)) {
+  if (! connection_get_outbuf_len(TO_CONN(orconn))) {
     /* There is no data at all waiting to be sent on the outbuf.  Add a
      * cell, so that we can notice when it gets flushed, flushed_some can
      * get called, and we can start putting more data onto the buffer then.
-- 
1.7.1




More information about the tor-commits mailing list