Changeset 626

Show
Ignore:
Timestamp:
11/07/08 22:43:57 (4 months ago)
Author:
markdoliner
Message:

* Change rate.c to reset the start of the window when rate_add() is

called rather than when rate_check() is called. This fixes a problem
where we would always eventually hit the rate limit because we
weren't actually respecting the window size.

* Change c2s to close a client connection if it exceeds the rate limit
* Change c2s to log to the normal log and not the debug log when a user

is throttled.

* Change c2s to only try to read the amount of data up to the rate

limit--never more.

* Change c2s to call rate_add() to keep track of how much data each

client sends.

Location:
trunk
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/c2s/c2s.c

    r525 r626  
    5959                    } 
    6060 
    61                     log_debug(ZONE, "%d is throttled, delaying read", sess->fd->fd); 
    62  
    63                     buf->len = 0; 
    64                     return 0; 
     61                    log_write(sess->c2s->log, LOG_NOTICE, "%d is throttled, disconnecting", sess->fd->fd); 
     62 
     63                    /* Disconnect the user.  Ideally we would just stop 
     64                       reading from their socket until the throttle time 
     65                       expires.  But that's difficult. */ 
     66                    sx_kill(s); 
     67                    return -1; 
    6568                } 
    6669 
     
    7174            } 
    7275 
     76            /* no limit, just read as much as we can */ 
     77            else 
     78                rlen = buf->len; 
     79 
    7380            /* do the read */ 
    74             len = recv(sess->fd->fd, buf->data, buf->len, 0); 
     81            len = recv(sess->fd->fd, buf->data, rlen, 0); 
     82 
     83            /* update rate limits */ 
     84            if(sess->rate != NULL) 
     85                rate_add(sess->rate, len); 
    7586 
    7687            if(len < 0) { 
  • trunk/ChangeLog

    r625 r626  
     12008-07-11 Mark Doliner <mark@meebo.com> 
     2        * Fix c2s's byte rate limiting. 
     3        * Make c2s's connection rate limiting and router's byte rate limiting 
     4          work better. 
     5 
    162008-07-09 Mark Doliner <mark@meebo.com> 
    27        * Add a note to sm.xml that our Berkeley DB storage module doesn't 
  • trunk/util/rate.c

    r545 r626  
    4848void rate_add(rate_t rt, int count) 
    4949{ 
     50    time_t now; 
     51 
     52    now = time(NULL); 
     53 
     54    /* rate expired */ 
     55    if(now - rt->time >= rt->seconds) 
     56        rate_reset(rt); 
     57 
    5058    rt->count += count; 
    5159 
    5260    /* first event, so set the time */ 
    5361    if(rt->time == 0) 
    54         rt->time = time(NULL); 
     62        rt->time = now; 
    5563 
    5664    /* uhoh, they stuffed up */ 
    5765    if(rt->count >= rt->total) 
    58         rt->bad = time(NULL); 
     66        rt->bad = now; 
    5967} 
    6068 
     
    7078int rate_check(rate_t rt) 
    7179{ 
    72     time_t now; 
    73  
    7480    /* not tracking */ 
    7581    if(rt->time == 0) 
     
    8086        return 1; 
    8187 
    82     now = time(NULL); 
    83  
    8488    /* currently bad */ 
    8589    if(rt->bad != 0) 
    8690    { 
    8791        /* wait over, they're good again */ 
    88         if(now - rt->bad >= rt->wait) 
     92        if(time(NULL) - rt->bad >= rt->wait) 
    8993        { 
    9094            rate_reset(rt); 
     
    96100    } 
    97101 
    98     /* rate expired */ 
    99     if(now - rt->time >= rt->seconds) 
    100     { 
    101         rate_reset(rt); 
    102         return 1; 
    103     } 
    104  
    105102    /* they're inside the time, and not bad yet */ 
    106103    return 1; 
  • trunk/util/util.h

    r602 r626  
    268268JABBERD2_API void        rate_free(rate_t rt); 
    269269JABBERD2_API void        rate_reset(rate_t rt); 
     270 
     271/** 
     272 * Add a number of events to the counter.  This takes care of moving 
     273 * the sliding window, if we've moved outside the previous window. 
     274 */ 
    270275JABBERD2_API void        rate_add(rate_t rt, int count); 
     276 
     277/** 
     278 * @return The amount of events we have left before we hit the rate 
     279 *         limit.  This could be number of bytes, or number of 
     280 *         connection attempts, etc. 
     281 */ 
    271282JABBERD2_API int         rate_left(rate_t rt); 
    272 JABBERD2_API int         rate_check(rate_t rt);          /* 1 == good, 0 == bad */ 
     283 
     284/** 
     285 * @return 1 if we're under the rate limit and everything is fine or 
     286 *         0 if the rate limit has been exceeded and we should throttle 
     287 *         something. 
     288 */ 
     289JABBERD2_API int         rate_check(rate_t rt); 
    273290 
    274291/*