Tor  0.4.7.0-alpha-dev
ratelim.c
Go to the documentation of this file.
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 rate_limit_is_ready(ratelim_t *lim, time_t now)
23 {
24  if (lim->rate + lim->last_allowed <= now) {
25  int res = lim->n_calls_since_last_time + 1;
26  lim->last_allowed = now;
27  lim->n_calls_since_last_time = 0;
28  return res;
29  } else {
30  if (lim->n_calls_since_last_time <= RATELIM_TOOMANY) {
32  }
33 
34  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 rate_limit_log(ratelim_t *lim, time_t now)
43 {
44  int n;
45  if ((n = rate_limit_is_ready(lim, now))) {
46  time_t started_limiting = lim->started_limiting;
47  lim->started_limiting = 0;
48  if (n == 1) {
49  return tor_strdup("");
50  } else {
51  char *cp=NULL;
52  const char *opt_over = (n >= RATELIM_TOOMANY) ? "over " : "";
53  unsigned difference = (unsigned)(now - started_limiting);
54  difference = round_to_next_multiple_of(difference, 60);
55  tor_asprintf(&cp,
56  " [%s%d similar message(s) suppressed in last %d seconds]",
57  opt_over, n-1, (int)difference);
58  return cp;
59  }
60  } else {
61  if (lim->started_limiting == 0) {
62  lim->started_limiting = now;
63  }
64  return NULL;
65  }
66 }
Headers for util_malloc.c.
unsigned round_to_next_multiple_of(unsigned number, unsigned divisor)
Definition: muldiv.c:21
Header for muldiv.c.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
Header for printf.c.
char * rate_limit_log(ratelim_t *lim, time_t now)
Definition: ratelim.c:42
static int rate_limit_is_ready(ratelim_t *lim, time_t now)
Definition: ratelim.c:22
Summarize similar messages that would otherwise flood the logs.
int n_calls_since_last_time
Definition: ratelim.h:51
time_t last_allowed
Definition: ratelim.h:46
int rate
Definition: ratelim.h:44
time_t started_limiting
Definition: ratelim.h:48