summaryrefslogtreecommitdiffstats
path: root/third_party/libjingle/files/talk/xmpp/ratelimitmanager.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libjingle/files/talk/xmpp/ratelimitmanager.h')
-rw-r--r--third_party/libjingle/files/talk/xmpp/ratelimitmanager.h146
1 files changed, 146 insertions, 0 deletions
diff --git a/third_party/libjingle/files/talk/xmpp/ratelimitmanager.h b/third_party/libjingle/files/talk/xmpp/ratelimitmanager.h
new file mode 100644
index 0000000..79960d8
--- /dev/null
+++ b/third_party/libjingle/files/talk/xmpp/ratelimitmanager.h
@@ -0,0 +1,146 @@
+/*
+ * libjingle
+ * Copyright 2004--2006, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RATELIMITMANAGER_H_
+#define _RATELIMITMANAGER_H_
+
+#include "talk/base/time.h"
+#include "talk/base/taskrunner.h"
+#include <map>
+
+namespace buzz {
+
+/////////////////////////////////////////////////////////////////////
+//
+// RATELIMITMANAGER
+//
+/////////////////////////////////////////////////////////////////////
+//
+// RateLimitManager imposes client-side rate limiting for xmpp tasks and
+// other events. It ensures that no more than i events with a given name
+// can occur within k seconds.
+//
+// A buffer tracks the previous max_count events. Before an event is allowed
+// to occur, it can check its rate limit with a call to VerifyRateLimit.
+// VerifyRateLimit will look up the i-th to last event and if more than
+// k seconds have passed since then, it will return true and update the
+// appropriate rate limits. Else, it will return false.
+//
+/////////////////////////////////////////////////////////////////////
+
+class RateLimitManager {
+ public:
+
+ RateLimitManager() { };
+ ~RateLimitManager() {
+ for (RateLimitMap::iterator it = rate_limits_.begin();
+ it != rate_limits_.end(); ++it) {
+ delete it->second;
+ }
+ };
+
+ // Checks if the event is under the defined rate limit and updates the
+ // rate limit if so. Returns true if it's under the rate limit.
+ bool VerifyRateLimit(const std::string event_name, int max_count,
+ int per_x_seconds);
+
+ // Checks if the event is under the defined rate limit and updates the
+ // rate limit if so *or* if always_update = true.
+ bool VerifyRateLimit(const std::string event_name, int max_count,
+ int per_x_seconds, bool always_update);
+
+ private:
+ class RateLimit {
+ public:
+ RateLimit(int max, int per_x_secs) : counter_(0), max_count_(max),
+ per_x_seconds_(per_x_secs) {
+ event_times_ = new uint32[max_count_];
+ for (int i = 0; i < max_count_; i++) {
+ event_times_[i] = 0;
+ }
+ }
+
+ ~RateLimit() {
+ if (event_times_) {
+ delete[] event_times_;
+ }
+ }
+
+ // True iff the current time >= to the next song allowed time
+ bool IsWithinRateLimit() {
+ uint32 current_time = talk_base::Time();
+ if (talk_base::TimeDiff(current_time, NextTimeAllowedForCounter()) >= 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // Updates time and counter for rate limit
+ void UpdateRateLimit() {
+ event_times_[counter_] = talk_base::Time();
+ counter_ = (counter_ + 1) % max_count_;
+ }
+
+ private:
+
+ // The time at which the i-th (where i = max_count) event occured
+ uint32 PreviousTimeAtCounter() {
+ return event_times_[counter_];
+ }
+
+ // The time that the next event is allowed to occur
+ uint32 NextTimeAllowedForCounter() {
+ return PreviousTimeAtCounter() + per_x_seconds_ * talk_base::kSecToMsec;
+ }
+
+ int counter_; // count modulo max_count of the current event
+ int max_count_; // max number of events that can occur within per_x_seconds
+ int per_x_seconds_; // interval size for rate limit
+ uint32* event_times_; // buffer of previous max_count event
+ };
+
+ typedef std::map<const std::string, RateLimit*> RateLimitMap;
+
+ // Maps from event name to its rate limit
+ RateLimitMap rate_limits_;
+
+ // Returns rate limit for event with specified name
+ RateLimit* GetRateLimit(const std::string event_name);
+
+ // True iff the current time >= to the next song allowed time
+ bool IsWithinRateLimit(const std::string event_name);
+
+ // Updates time and counter for rate limit
+ void UpdateRateLimit(const std::string event_name, int max_count,
+ int per_x_seconds);
+
+};
+
+}
+
+#endif //_RATELIMITMANAGER_H_