comparison plugins/mod_limits.lua @ 14144:e38916e22f59 13.0

mod_limits: Only count connections with associated sessions I suspect some (all??) network backends and some edge cases cause ondisconnect to be called more than once. mod_c2s and mod_s2s already handle this, skipping cleanup if there is no session associated. Sessions are assigned very early on in onconnect, so it seems like a reliable way of counting.
author Matthew Wild <mwild1@gmail.com>
date Fri, 17 Apr 2026 19:42:44 +0100
parents 4087c5b600b1
children 4b8cf9420cf1
comparison
equal deleted inserted replaced
14143:723c6f5f01b7 14144:e38916e22f59
65 65
66 local function limit_ip_sessions(session_type, max_sessions) 66 local function limit_ip_sessions(session_type, max_sessions)
67 -- [packed_truncated_ip] = count 67 -- [packed_truncated_ip] = count
68 local current_ips = module:shared("ips."..session_type); 68 local current_ips = module:shared("ips."..session_type);
69 module:hook(session_type.."-connected", function (event) 69 module:hook(session_type.."-connected", function (event)
70 if not event.session then return; end
70 local session_ip = get_truncated_ip(event.conn); 71 local session_ip = get_truncated_ip(event.conn);
71 local new_count = (current_ips[session_ip] or 0) + 1; 72 local new_count = (current_ips[session_ip] or 0) + 1;
72 current_ips[session_ip] = new_count; 73 current_ips[session_ip] = new_count;
73 if new_count > max_sessions then 74 if new_count > max_sessions then
74 module:log("warn", "Rejecting stream from %s (%d of %d current connections)", event.conn:ip(), new_count, max_sessions); 75 module:log("warn", "Rejecting stream from %s (%d of %d current connections)", event.conn:ip(), new_count, max_sessions);
75 event.session:close({ condition = "policy-violation", text = "too many connections" }); 76 event.session:close({ condition = "policy-violation", text = "too many connections" });
76 end 77 end
77 end); 78 end);
78 79
79 module:hook(session_type.."-closed", function (event) 80 module:hook(session_type.."-closed", function (event)
81 if not event.session then return; end
80 local session_ip = get_truncated_ip(event.conn); 82 local session_ip = get_truncated_ip(event.conn);
81 local new_count = (current_ips[session_ip] or 0) - 1; 83 local new_count = (current_ips[session_ip] or 0) - 1;
82 if new_count < 0 then 84 if new_count < 0 then
83 module:log("warn", "IP counting failure"); 85 module:log("warn", "IP counting failure");
84 new_count = 0; 86 new_count = 0;