From f28e65ab8035682372edbe1c11d9ca2581e0a2e6 Mon Sep 17 00:00:00 2001 From: marzavec Date: Wed, 6 Nov 2019 23:35:23 -0800 Subject: Syntax update and formatting tweaks --- server/src/serverLib/RateLimiter.js | 105 +++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 31 deletions(-) (limited to 'server/src/serverLib/RateLimiter.js') diff --git a/server/src/serverLib/RateLimiter.js b/server/src/serverLib/RateLimiter.js index 43cf077..3f9bc27 100644 --- a/server/src/serverLib/RateLimiter.js +++ b/server/src/serverLib/RateLimiter.js @@ -1,39 +1,60 @@ +import { RateLimits } from '../utility/Constants'; + /** * Tracks frequency of occurances based on `id` (remote address), then allows or * denies command execution based on comparison with `threshold` - * - * Version: v2.0.0 - * Developer: Marzavec ( https://github.com/marzavec ) - * License: WTFPL ( http://www.wtfpl.net/txt/copying/ ) - * + * @property {Object} data - The current stats data + * @author Marzavec ( https://github.com/marzavec ) + * @author Andrew Belt ( https://github.com/AndrewBelt ) + * @version v2.0.0 + * @license WTFPL ( http://www.wtfpl.net/txt/copying/ ) */ - class RateLimiter { /** - * Create a ratelimiter instance. - */ - constructor () { + * Create a ratelimiter instance + */ + constructor() { + /** + * Data holder rate limit records + * @type {Object} + */ this.records = {}; - this.halflife = 30 * 1000; // milliseconds - this.threshold = 25; + + /** + * Time in milliseconds to decrement ratelimit weight + * @type {Number} + */ + this.halflife = RateLimits.halflife; + + /** + * Weight until ratelimited + * @type {Number} + */ + this.threshold = RateLimits.threshold; + + /** + * Stores the associated connection fingerprint with record id + * @type {Array} + */ this.hashes = []; } /** * Finds current score by `id` - * * @param {String} id target id / address - * + * @private * @return {Object} Object containing the record meta */ - search (id) { + search(id) { let record = this.records[id]; if (!record) { - record = this.records[id] = { + this.records[id] = { time: Date.now(), - score: 0 - } + score: 0, + }; + + record = this.records[id]; } return record; @@ -41,20 +62,22 @@ class RateLimiter { /** * Adjusts the current ratelimit score by `deltaScore` - * * @param {String} id target id / address * @param {Number} deltaScore amount to adjust current score by - * + * @example + * // Penalize by 1 and store if connection is ratelimited or not + * let isLimited = police.frisk(socket.address, 1); + * @public * @return {Boolean} True if record threshold has been exceeded */ - frisk (id, deltaScore) { - let record = this.search(id); + frisk(id, deltaScore) { + const record = this.search(id); if (record.arrested) { return true; } - record.score *= Math.pow(2, -(Date.now() - record.time ) / this.halflife); + record.score *= 2 ** -(Date.now() - record.time) / this.halflife; record.score += deltaScore; record.time = Date.now(); @@ -67,11 +90,16 @@ class RateLimiter { /** * Statically set server to no longer accept traffic from `id` - * * @param {String} id target id / address + * @example + * // Usage within a command module: + * let badClient = server.findSockets({ channel: socket.channel, nick: targetNick }); + * server.police.arrest(badClient[0].address, badClient[0].hash); + * @public + * @return {void} */ - arrest (id, hash) { - let record = this.search(id); + arrest(id, hash) { + const record = this.search(id); record.arrested = true; this.hashes[hash] = id; @@ -79,17 +107,32 @@ class RateLimiter { /** * Remove statically assigned limit from `id` - * * @param {String} id target id / address + * @example + * // Usage within a command module: + * server.police.pardon('targetHashOrIP'); + * @public + * @return {void} */ - pardon (id) { - if (typeof this.hashes[id] !== 'undefined') { - id = this.hashes[id]; + pardon(id) { + let targetId = id; + if (typeof this.hashes[targetId] !== 'undefined') { + targetId = this.hashes[targetId]; } - let record = this.search(id); + const record = this.search(targetId); record.arrested = false; } + + /** + * Clear all records + * @public + * @return {void} + */ + clear() { + this.records = {}; + this.hashes = []; + } } -module.exports = RateLimiter; +export default RateLimiter; -- cgit v1.2.1