aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-08-24 17:57:55 -0400
committerNick Mathewson <nickm@torproject.org>2011-08-24 17:57:55 -0400
commitb161674d5dc312f95a495bed3c25d892fc9f0550 (patch)
tree2b8e5ef9064ad4340708f974d4c9ee2052201be3
parentede9cd4f99e4cd1c0c4bcf1a3ac994e87054cc2d (diff)
parentdfcd3d9ce00dedcf00124c9329985c5522f286dc (diff)
downloadtor-b161674d5dc312f95a495bed3c25d892fc9f0550.tar
tor-b161674d5dc312f95a495bed3c25d892fc9f0550.tar.gz
Merge branch 'bufev_ratelim_and_wm'
-rw-r--r--changes/bug38049
-rw-r--r--changes/bug38055
-rw-r--r--src/common/compat_libevent.c26
-rw-r--r--src/common/compat_libevent.h6
-rw-r--r--src/common/tortls.c5
-rw-r--r--src/or/connection.c7
-rw-r--r--src/or/connection_or.c4
7 files changed, 59 insertions, 3 deletions
diff --git a/changes/bug3804 b/changes/bug3804
new file mode 100644
index 000000000..7ad091c17
--- /dev/null
+++ b/changes/bug3804
@@ -0,0 +1,9 @@
+ o Major bugfixes (bufferevents):
+ - Apply rate-limiting only at the bottom of a chain of filtering
+ bufferevents. This prevents us from filling up internal read
+ buffers and violating rate-limits when filtering bufferevents
+ are enabled. Bugfix on 0.2.3.1-alpha; fixes part of bug 3804.
+ - Add high-watermarks to the output buffers for filtered
+ bufferevents. This prevents us from filling up internal write
+ buffers and wasting CPU cycles when filtering bufferevents are
+ enabled. Bugfix on 0.2.3.1-alpha; fixes part of bug 3804.
diff --git a/changes/bug3805 b/changes/bug3805
new file mode 100644
index 000000000..9d12b8146
--- /dev/null
+++ b/changes/bug3805
@@ -0,0 +1,5 @@
+ o Major bugfixes (bufferevents):
+ - Correctly notice when data has been written from a bufferevent
+ without flushing it completely. Bugfix on 0.2.3.1-alpha; fixes
+ bug 3805.
+
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index 595742f96..beae9502d 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -20,6 +20,9 @@
#ifdef HAVE_EVENT2_EVENT_H
#include <event2/event.h>
#include <event2/thread.h>
+#ifdef USE_BUFFEREVENTS
+#include <event2/bufferevent.h>
+#endif
#else
#include <event.h>
#endif
@@ -614,5 +617,28 @@ tor_libevent_get_one_tick_timeout(void)
}
return one_tick;
}
+
+static struct bufferevent *
+tor_get_root_bufferevent(struct bufferevent *bev)
+{
+ struct bufferevent *u;
+ while ((u = bufferevent_get_underlying(bev)) != NULL)
+ bev = u;
+ return bev;
+}
+
+int
+tor_set_bufferevent_rate_limit(struct bufferevent *bev,
+ struct ev_token_bucket_cfg *cfg)
+{
+ return bufferevent_set_rate_limit(tor_get_root_bufferevent(bev), cfg);
+}
+
+int
+tor_add_bufferevent_to_rate_limit_group(struct bufferevent *bev,
+ struct bufferevent_rate_limit_group *g)
+{
+ return bufferevent_add_to_rate_limit_group(tor_get_root_bufferevent(bev), g);
+}
#endif
diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h
index bbe105bf4..15b0fc273 100644
--- a/src/common/compat_libevent.h
+++ b/src/common/compat_libevent.h
@@ -10,6 +10,8 @@ struct event;
struct event_base;
#ifdef USE_BUFFEREVENTS
struct bufferevent;
+struct ev_token_bucket_cfg;
+struct bufferevent_rate_limit_group;
#endif
#ifdef HAVE_EVENT2_EVENT_H
@@ -74,6 +76,10 @@ const char *tor_libevent_get_version_str(void);
#define TOR_LIBEVENT_TICKS_PER_SECOND 3
const struct timeval *tor_libevent_get_one_tick_timeout(void);
int tor_libevent_using_iocp_bufferevents(void);
+int tor_set_bufferevent_rate_limit(struct bufferevent *bev,
+ struct ev_token_bucket_cfg *cfg);
+int tor_add_bufferevent_to_rate_limit_group(struct bufferevent *bev,
+ struct bufferevent_rate_limit_group *g);
#endif
#endif
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 2aaa2c49b..1bb9c74ef 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -51,6 +51,7 @@
#ifdef USE_BUFFEREVENTS
#include <event2/bufferevent_ssl.h>
#include <event2/buffer.h>
+#include <event2/event.h>
#include "compat_libevent.h"
#endif
@@ -1905,6 +1906,10 @@ tor_tls_init_bufferevent(tor_tls_t *tls, struct bufferevent *bufev_in,
state,
BEV_OPT_DEFER_CALLBACKS|
BEV_OPT_CLOSE_ON_FREE);
+ /* Tell the underlying bufferevent when to accept more data from the SSL
+ filter (only when it's got less than 32K to write), and when to notify
+ the SSL filter that it could write more (when it drops under 24K). */
+ bufferevent_setwatermark(bufev_in, EV_WRITE, 24*1024, 32*1024);
} else {
if (bufev_in) {
evutil_socket_t s = bufferevent_getfd(bufev_in);
diff --git a/src/or/connection.c b/src/or/connection.c
index f8f82a30d..dc804ddce 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -2509,7 +2509,7 @@ connection_enable_rate_limiting(connection_t *conn)
if (conn->bufev) {
if (!global_rate_limit)
connection_bucket_init();
- bufferevent_add_to_rate_limit_group(conn->bufev, global_rate_limit);
+ tor_add_bufferevent_to_rate_limit_group(conn->bufev, global_rate_limit);
}
}
@@ -2947,6 +2947,11 @@ connection_configure_bufferevent_callbacks(connection_t *conn)
connection_handle_write_cb,
connection_handle_event_cb,
conn);
+ /* Set a fairly high write low-watermark so that we get the write callback
+ called whenever data is written to bring us under 128K. Leave the
+ high-watermark at 0.
+ */
+ bufferevent_setwatermark(bufev, EV_WRITE, 128*1024, 0);
input = bufferevent_get_input(bufev);
output = bufferevent_get_output(bufev);
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index e66d36a2f..a75444e1e 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -585,7 +585,7 @@ connection_or_update_token_buckets_helper(or_connection_t *conn, int reset,
burst, tick);
old_cfg = conn->bucket_cfg;
if (conn->_base.bufev)
- bufferevent_set_rate_limit(conn->_base.bufev, cfg);
+ tor_set_bufferevent_rate_limit(conn->_base.bufev, cfg);
if (old_cfg)
ev_token_bucket_cfg_free(old_cfg);
conn->bucket_cfg = cfg;
@@ -1102,7 +1102,7 @@ connection_tls_start_handshake(or_connection_t *conn, int receiving)
}
conn->_base.bufev = b;
if (conn->bucket_cfg)
- bufferevent_set_rate_limit(conn->_base.bufev, conn->bucket_cfg);
+ tor_set_bufferevent_rate_limit(conn->_base.bufev, conn->bucket_cfg);
connection_enable_rate_limiting(TO_CONN(conn));
connection_configure_bufferevent_callbacks(TO_CONN(conn));