From 2cbb1a161e843a0f50f3d42f622d58d5c58c510d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 26 Oct 2010 10:27:29 -0400 Subject: [PATCH] Make rate-limits go up to SIZE_MAX/EV_SSIZE_MAX, not just INT32_MAX Someday, when networks are far faster and people frequently want a burst value greater than 2GB per tick, this will seem very forsightful indeed. For now, it breaks ABI, but not source. Fixes bug 3092096. --- bufferevent-internal.h | 2 +- bufferevent_ratelim.c | 25 +++++++++++++++---------- include/event2/bufferevent.h | 7 +++++-- ratelim-internal.h | 10 +++++----- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/bufferevent-internal.h b/bufferevent-internal.h index 1b817f6c..b7b598fa 100644 --- a/bufferevent-internal.h +++ b/bufferevent-internal.h @@ -96,7 +96,7 @@ struct bufferevent_rate_limit_group { /** The smallest number of bytes that any member of the group should * be limited to read or write at a time. */ - ev_int32_t min_share; + ev_ssize_t min_share; /** Timeout event that goes off once a tick, when the bucket is ready * to refill. */ struct event master_refill_event; diff --git a/bufferevent_ratelim.c b/bufferevent_ratelim.c index a70cd8db..1f3b4175 100644 --- a/bufferevent_ratelim.c +++ b/bufferevent_ratelim.c @@ -138,8 +138,8 @@ ev_token_bucket_get_tick(const struct timeval *tv, } struct ev_token_bucket_cfg * -ev_token_bucket_cfg_new(ev_uint32_t read_rate, ev_uint32_t read_burst, - ev_uint32_t write_rate, ev_uint32_t write_burst, +ev_token_bucket_cfg_new(size_t read_rate, size_t read_burst, + size_t write_rate, size_t write_burst, const struct timeval *tick_len) { struct ev_token_bucket_cfg *r; @@ -152,6 +152,11 @@ ev_token_bucket_cfg_new(ev_uint32_t read_rate, ev_uint32_t read_burst, if (read_rate > read_burst || write_rate > write_burst || read_rate < 1 || write_rate < 1) return NULL; + if (read_rate > EV_RATE_LIMIT_MAX || + write_rate > EV_RATE_LIMIT_MAX || + read_burst > EV_RATE_LIMIT_MAX || + write_burst > EV_RATE_LIMIT_MAX) + return NULL; r = mm_calloc(1, sizeof(struct ev_token_bucket_cfg)); if (!r) return NULL; @@ -221,7 +226,7 @@ _bufferevent_get_rlim_max(struct bufferevent_private *bev, int is_write) if (bev->rate_limiting->group) { struct bufferevent_rate_limit_group *g = bev->rate_limiting->group; - ev_int32_t share; + ev_ssize_t share; LOCK_GROUP(g); if (GROUP_SUSPENDED(g)) { /* We can get here if we failed to lock this @@ -655,9 +660,9 @@ bufferevent_rate_limit_group_set_cfg( &g->rate_limit_cfg.tick_timeout, &cfg->tick_timeout, ==); memcpy(&g->rate_limit_cfg, cfg, sizeof(g->rate_limit_cfg)); - if (g->rate_limit.read_limit > (ev_int32_t)cfg->read_maximum) + if (g->rate_limit.read_limit > (ev_ssize_t)cfg->read_maximum) g->rate_limit.read_limit = cfg->read_maximum; - if (g->rate_limit.write_limit > (ev_int32_t)cfg->write_maximum) + if (g->rate_limit.write_limit > (ev_ssize_t)cfg->write_maximum) g->rate_limit.write_limit = cfg->write_maximum; if (!same_tick) { @@ -674,7 +679,7 @@ bufferevent_rate_limit_group_set_min_share( struct bufferevent_rate_limit_group *g, size_t share) { - if (share > EV_INT32_MAX) + if (share > EV_SSIZE_MAX) return -1; g->min_share = share; @@ -865,7 +870,7 @@ int bufferevent_decrement_read_limit(struct bufferevent *bev, ev_ssize_t decr) { int r = 0; - ev_int32_t old_limit, new_limit; + ev_ssize_t old_limit, new_limit; struct bufferevent_private *bevp; BEV_LOCK(bev); bevp = BEV_UPCAST(bev); @@ -894,7 +899,7 @@ bufferevent_decrement_write_limit(struct bufferevent *bev, ev_ssize_t decr) /* XXXX this is mostly copy-and-paste from * bufferevent_decrement_read_limit */ int r = 0; - ev_int32_t old_limit, new_limit; + ev_ssize_t old_limit, new_limit; struct bufferevent_private *bevp; BEV_LOCK(bev); bevp = BEV_UPCAST(bev); @@ -922,7 +927,7 @@ bufferevent_rate_limit_group_decrement_read( struct bufferevent_rate_limit_group *grp, ev_ssize_t decr) { int r = 0; - ev_int32_t old_limit, new_limit; + ev_ssize_t old_limit, new_limit; LOCK_GROUP(grp); old_limit = grp->rate_limit.read_limit; new_limit = (grp->rate_limit.read_limit -= decr); @@ -942,7 +947,7 @@ bufferevent_rate_limit_group_decrement_write( struct bufferevent_rate_limit_group *grp, ev_ssize_t decr) { int r = 0; - ev_int32_t old_limit, new_limit; + ev_ssize_t old_limit, new_limit; LOCK_GROUP(grp); old_limit = grp->rate_limit.write_limit; new_limit = (grp->rate_limit.write_limit -= decr); diff --git a/include/event2/bufferevent.h b/include/event2/bufferevent.h index 5155d251..ee84e084 100644 --- a/include/event2/bufferevent.h +++ b/include/event2/bufferevent.h @@ -565,6 +565,9 @@ struct ev_token_bucket_cfg; */ struct bufferevent_rate_limit_group; +/** Maximum configurable rate- or burst-limit. */ +#define EV_RATE_LIMIT_MAX EV_SSIZE_MAX + /** Initialize and return a new object to configure the rate-limiting behavior of bufferevents. @@ -582,8 +585,8 @@ struct bufferevent_rate_limit_group; of Libevent may implement them more tightly. */ struct ev_token_bucket_cfg *ev_token_bucket_cfg_new( - ev_uint32_t read_rate, ev_uint32_t read_burst, - ev_uint32_t write_rate, ev_uint32_t write_burst, + size_t read_rate, size_t read_burst, + size_t write_rate, size_t write_burst, const struct timeval *tick_len); /** Free all storage held in 'cfg'. diff --git a/ratelim-internal.h b/ratelim-internal.h index d60f6376..043e5b2d 100644 --- a/ratelim-internal.h +++ b/ratelim-internal.h @@ -38,7 +38,7 @@ extern "C" { struct ev_token_bucket { /** How many bytes are we willing to read or write right now? These * values are signed so that we can do "defecit spending" */ - ev_int32_t read_limit, write_limit; + ev_ssize_t read_limit, write_limit; /** When was this bucket last updated? Measured in abstract 'ticks' * relative to the token bucket configuration. */ ev_uint32_t last_updated; @@ -47,13 +47,13 @@ struct ev_token_bucket { /** Configuration info for a token bucket or set of token buckets. */ struct ev_token_bucket_cfg { /** How many bytes are we willing to read on average per tick? */ - ev_uint32_t read_rate; + size_t read_rate; /** How many bytes are we willing to read at most in any one tick? */ - ev_uint32_t read_maximum; + size_t read_maximum; /** How many bytes are we willing to write on average per tick? */ - ev_uint32_t write_rate; + size_t write_rate; /** How many bytes are we willing to write at most in any one tick? */ - ev_uint32_t write_maximum; + size_t write_maximum; /* How long is a tick? Note that fractions of a millisecond are * ignored. */ -- 2.40.0