Apply rate-limiting to the lowest bufferevent in the stack.

When we're doing filtering ssl bufferevents, we want the rate-limits
to apply to the lowest level of the bufferevent stack, so that we're
actually limiting bytes sent on the network. Otherwise, we'll read
from the network aggressively, and only limit stuff as we process it.
This commit is contained in:
Nick Mathewson 2011-08-24 17:09:56 -04:00
parent ede9cd4f99
commit 59d0f750c9
5 changed files with 39 additions and 3 deletions

4
changes/bug3804 Normal file
View File

@ -0,0 +1,4 @@
o Major bugfixes (bufferevents):
- Apply rate-limiting only at the bottom of a chain of filtering
bufferevents. This prevents us from filling up internal memory
buffers. Bugfix on 0.2.3.1-alpha; fixes bug 3804.

View File

@ -20,6 +20,9 @@
#ifdef HAVE_EVENT2_EVENT_H #ifdef HAVE_EVENT2_EVENT_H
#include <event2/event.h> #include <event2/event.h>
#include <event2/thread.h> #include <event2/thread.h>
#ifdef USE_BUFFEREVENTS
#include <event2/bufferevent.h>
#endif
#else #else
#include <event.h> #include <event.h>
#endif #endif
@ -614,5 +617,28 @@ tor_libevent_get_one_tick_timeout(void)
} }
return one_tick; 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 #endif

View File

@ -10,6 +10,8 @@ struct event;
struct event_base; struct event_base;
#ifdef USE_BUFFEREVENTS #ifdef USE_BUFFEREVENTS
struct bufferevent; struct bufferevent;
struct ev_token_bucket_cfg;
struct bufferevent_rate_limit_group;
#endif #endif
#ifdef HAVE_EVENT2_EVENT_H #ifdef HAVE_EVENT2_EVENT_H
@ -74,6 +76,10 @@ const char *tor_libevent_get_version_str(void);
#define TOR_LIBEVENT_TICKS_PER_SECOND 3 #define TOR_LIBEVENT_TICKS_PER_SECOND 3
const struct timeval *tor_libevent_get_one_tick_timeout(void); const struct timeval *tor_libevent_get_one_tick_timeout(void);
int tor_libevent_using_iocp_bufferevents(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
#endif #endif

View File

@ -2509,7 +2509,7 @@ connection_enable_rate_limiting(connection_t *conn)
if (conn->bufev) { if (conn->bufev) {
if (!global_rate_limit) if (!global_rate_limit)
connection_bucket_init(); 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);
} }
} }

View File

@ -585,7 +585,7 @@ connection_or_update_token_buckets_helper(or_connection_t *conn, int reset,
burst, tick); burst, tick);
old_cfg = conn->bucket_cfg; old_cfg = conn->bucket_cfg;
if (conn->_base.bufev) if (conn->_base.bufev)
bufferevent_set_rate_limit(conn->_base.bufev, cfg); tor_set_bufferevent_rate_limit(conn->_base.bufev, cfg);
if (old_cfg) if (old_cfg)
ev_token_bucket_cfg_free(old_cfg); ev_token_bucket_cfg_free(old_cfg);
conn->bucket_cfg = cfg; conn->bucket_cfg = cfg;
@ -1102,7 +1102,7 @@ connection_tls_start_handshake(or_connection_t *conn, int receiving)
} }
conn->_base.bufev = b; conn->_base.bufev = b;
if (conn->bucket_cfg) 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_enable_rate_limiting(TO_CONN(conn));
connection_configure_bufferevent_callbacks(TO_CONN(conn)); connection_configure_bufferevent_callbacks(TO_CONN(conn));