ratelim.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "lib/log/ratelim.h"
  6. #include "lib/malloc/util_malloc.h"
  7. #include "lib/string/printf.h"
  8. /** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return the number
  9. * of calls to rate_limit_is_ready (including this one!) since the last time
  10. * rate_limit_is_ready returned nonzero. Otherwise return 0.
  11. * If the call number hits <b>RATELIM_TOOMANY</b> limit, drop a warning
  12. * about this event and stop counting. */
  13. static int
  14. rate_limit_is_ready(ratelim_t *lim, time_t now)
  15. {
  16. if (lim->rate + lim->last_allowed <= now) {
  17. int res = lim->n_calls_since_last_time + 1;
  18. lim->last_allowed = now;
  19. lim->n_calls_since_last_time = 0;
  20. return res;
  21. } else {
  22. if (lim->n_calls_since_last_time <= RATELIM_TOOMANY) {
  23. ++lim->n_calls_since_last_time;
  24. }
  25. return 0;
  26. }
  27. }
  28. /** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return a newly
  29. * allocated string indicating how many messages were suppressed, suitable to
  30. * append to a log message. Otherwise return NULL. */
  31. char *
  32. rate_limit_log(ratelim_t *lim, time_t now)
  33. {
  34. int n;
  35. if ((n = rate_limit_is_ready(lim, now))) {
  36. if (n == 1) {
  37. return tor_strdup("");
  38. } else {
  39. char *cp=NULL;
  40. const char *opt_over = (n >= RATELIM_TOOMANY) ? "over " : "";
  41. /* XXXX this is not exactly correct: the messages could have occurred
  42. * any time between the old value of lim->allowed and now. */
  43. tor_asprintf(&cp,
  44. " [%s%d similar message(s) suppressed in last %d seconds]",
  45. opt_over, n-1, lim->rate);
  46. return cp;
  47. }
  48. } else {
  49. return NULL;
  50. }
  51. }