From 1c72eda6a9c1ca27c2b5ea7fe713906c9a0733c6 Mon Sep 17 00:00:00 2001 From: C-NERD Date: Sat, 17 Sep 2022 10:17:50 +0100 Subject: [PATCH] completed code for new tracker --- src/clown_limiter.nim | 2 +- src/clown_limiter/tracker.nim | 66 +++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/clown_limiter.nim b/src/clown_limiter.nim index 78de59e..8e11b8e 100644 --- a/src/clown_limiter.nim +++ b/src/clown_limiter.nim @@ -96,7 +96,7 @@ router clown_limiter: let ip = request.ip() rateinfo = ip.rateStatus(rate, freq) - + case rateinfo.status of Exceeded: diff --git a/src/clown_limiter/tracker.nim b/src/clown_limiter/tracker.nim index 56ea5ee..b1cc856 100644 --- a/src/clown_limiter/tracker.nim +++ b/src/clown_limiter/tracker.nim @@ -11,53 +11,65 @@ type NotExceeded Exceeded Expired - Tracker = object +var + write_lock : Lock + tracker : Table[string, tuple[calls, lastcalled : int]] ## to store ip address and number of calls made by address + tracker_addr = addr(tracker) - write_lock : Lock - ip_data {.guard : write_lock.} : Table[string, tuple[calls, lastcalled : int]] ## to store ip address and number of calls made by address +initLock(write_lock) -var tracker* {.global.} : Tracker -initLock(tracker.write_lock) +proc addIpToReqRate*(ip : string) {.gcsafe.} = -proc addIpToReqRate*(ip : string) = + var ip_data {.guard : write_lock.} = cast[ref Table[string, tuple[calls, lastcalled : int]]](tracker_addr) + withLock write_lock: - withLock tracker.write_lock: - - if ip in tracker.ip_data: + if ip in ip_data: return - tracker.ip_data[ip] = (calls : 1, lastcalled : int(epochTime())) - -proc recordReqRate*(ip : string, calls : int) = + ip_data[ip] = (calls : 1, lastcalled : int(epochTime())) - withLock tracker.write_lock: +proc recordReqRate*(ip : string, calls : int) {.gcsafe.} = - if ip in tracker.ip_data: + var ip_data {.guard : write_lock.} = cast[ref Table[string, tuple[calls, lastcalled : int]]](tracker_addr) + withLock write_lock: - tracker.ip_data[ip].calls = calls + 1 - tracker.ip_data[ip].lastcalled = int(epochTime()) + if ip in ip_data: -proc resetReqRate*(ip : string) : tuple[calls, lastcalled : int] {.discardable.} = + ip_data[ip].calls = calls + 1 + ip_data[ip].lastcalled = int(epochTime()) - withLock tracker.write_lock: +proc resetReqRate*(ip : string) : tuple[calls, lastcalled : int] {.discardable, gcsafe.} = - if ip in tracker.ip_data: + var ip_data {.guard : write_lock.} = cast[ref Table[string, tuple[calls, lastcalled : int]]](tracker_addr) + withLock write_lock: + + if ip in ip_data: - tracker.ip_data[ip].calls = 1 - tracker.ip_data[ip].lastcalled = int(epochTime()) + ip_data[ip].calls = 1 + ip_data[ip].lastcalled = int(epochTime()) - return (calls : 1, lastcalled : tracker.ip_data[ip].lastcalled) + return (calls : 1, lastcalled : ip_data[ip].lastcalled) -proc rateStatus*(ip : string, rate, freq : int) : tuple[status : RateStatus, calls : int] = +proc rateStatus*(ip : string, rate, freq : int) : tuple[status : RateStatus, calls : int] {.gcsafe.} = let + ip_data {.guard : write_lock.} = cast[ref Table[string, tuple[calls, lastcalled : int]]](tracker_addr) req_rate : tuple[calls, lastcalled : int] = block: - var req_rate : tuple[calls, lastcalled : int] = (1, 0) - withLock tracker.write_lock: + var + req_rate : tuple[calls, lastcalled : int] = (1, 0) + addip : bool = true + withLock write_lock: + + if ip in ip_data: + + addip = false + req_rate = ip_data[ip] + + if addip: - req_rate = tracker.ip_data[ip] + addIpToReqRate(ip) req_rate @@ -74,4 +86,4 @@ proc rateStatus*(ip : string, rate, freq : int) : tuple[status : RateStatus, cal else: - return (NotExceeded, req_rate.calls) + return (NotExceeded, req_rate.calls) \ No newline at end of file