LCOV - code coverage report
Current view: top level - lib/log - ratelim.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 25 25 100.0 %
Date: 2021-11-24 03:28:48 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2003-2004, Roger Dingledine
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : /**
       7             :  * \file ratelim.c
       8             :  * \brief Summarize similar messages that would otherwise flood the logs.
       9             :  **/
      10             : 
      11             : #include "lib/log/ratelim.h"
      12             : #include "lib/malloc/malloc.h"
      13             : #include "lib/string/printf.h"
      14             : #include "lib/intmath/muldiv.h"
      15             : 
      16             : /** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return the number
      17             :  * of calls to rate_limit_is_ready (including this one!) since the last time
      18             :  * rate_limit_is_ready returned nonzero.  Otherwise return 0.
      19             :  * If the call number hits <b>RATELIM_TOOMANY</b> limit, drop a warning
      20             :  * about this event and stop counting. */
      21             : static int
      22          32 : rate_limit_is_ready(ratelim_t *lim, time_t now)
      23             : {
      24          32 :   if (lim->rate + lim->last_allowed <= now) {
      25          18 :     int res = lim->n_calls_since_last_time + 1;
      26          18 :     lim->last_allowed = now;
      27          18 :     lim->n_calls_since_last_time = 0;
      28          18 :     return res;
      29             :   } else {
      30          14 :     if (lim->n_calls_since_last_time <= RATELIM_TOOMANY) {
      31          14 :       ++lim->n_calls_since_last_time;
      32             :     }
      33             : 
      34          14 :     return 0;
      35             :   }
      36             : }
      37             : 
      38             : /** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return a newly
      39             :  * allocated string indicating how many messages were suppressed, suitable to
      40             :  * append to a log message.  Otherwise return NULL. */
      41             : char *
      42          32 : rate_limit_log(ratelim_t *lim, time_t now)
      43             : {
      44          32 :   int n;
      45          32 :   if ((n = rate_limit_is_ready(lim, now))) {
      46          18 :     time_t started_limiting = lim->started_limiting;
      47          18 :     lim->started_limiting = 0;
      48          18 :     if (n == 1) {
      49          15 :       return tor_strdup("");
      50             :     } else {
      51           3 :       char *cp=NULL;
      52           3 :       const char *opt_over = (n >= RATELIM_TOOMANY) ? "over " : "";
      53           3 :       unsigned difference = (unsigned)(now - started_limiting);
      54           3 :       difference = round_to_next_multiple_of(difference, 60);
      55           3 :       tor_asprintf(&cp,
      56             :                    " [%s%d similar message(s) suppressed in last %d seconds]",
      57             :                    opt_over, n-1, (int)difference);
      58           3 :       return cp;
      59             :     }
      60             :   } else {
      61          14 :     if (lim->started_limiting == 0) {
      62           5 :       lim->started_limiting = now;
      63             :     }
      64          14 :     return NULL;
      65             :   }
      66             : }

Generated by: LCOV version 1.14