code wiki / _hdl_build / nx_conn_cap.nx

nx_conn_cap.nx source

↩ module page · 53 lines · 2130 B

1// nx_conn_cap.nx -- per-IP concurrent-connection cap, the access-wall DDoS L3-connection / slowloris defense 2// (RFC 7230 timeouts complement). A bounded in-memory table the enforcement daemon owns: cc_acquire(ip) at 3// accept (reject when an IP already holds >= cap, OR when the table is saturated = FAIL-CLOSED under a flood), 4// cc_release(ip) on close. Pure logic, nx_syscalls -- pairs with nx_rate_limit (request brute-force, L4) + 5// nx_access_wall (the rate_ok / conn-ok signals feed the PDP). license_tier: ORIGINAL 6import "nx_syscalls.nx" 7 8const CC_CAP_DEFAULT: i64 = 16 // default max concurrent connections per IP 9 10// find ip's slot in ips[0..n); -1 if absent. 11func cc_find(ips: *i64, n: i64, ip: i64) -> i64 { 12 var i: i64 = 0 13 while i < n { if ips[i] == ip { return i } i = i + 1 } 14 return 0 - 1 15} 16 17// try to acquire a connection slot for ip. ips/cnts = parallel tables, nbox[0] = used slots, slots = table 18// capacity, cap = max concurrent per IP. returns 1 (allowed, count++ ) or 0 (rejected: per-IP cap hit, or the 19// table is saturated -> fail-closed reject of a NEW flooding IP). 20func cc_acquire(ips: *i64, cnts: *i64, nbox: *i64, slots: i64, ip: i64, cap: i64) -> i64 { 21 let s: i64 = cc_find(ips, nbox[0], ip) 22 if s >= 0 { 23 if cnts[s] >= cap { return 0 } 24 cnts[s] = cnts[s] + 1 25 return 1 26 } 27 if nbox[0] >= slots { return 0 } 28 ips[nbox[0]] = ip 29 cnts[nbox[0]] = 1 30 nbox[0] = nbox[0] + 1 31 return 1 32} 33 34// release a connection slot for ip (on close): decrement; when it hits 0, free the slot (swap-with-last). 35func cc_release(ips: *i64, cnts: *i64, nbox: *i64, ip: i64) -> i64 { 36 let s: i64 = cc_find(ips, nbox[0], ip) 37 if s < 0 { return 0 } 38 if cnts[s] > 0 { cnts[s] = cnts[s] - 1 } 39 if cnts[s] == 0 { 40 let last: i64 = nbox[0] - 1 41 ips[s] = ips[last] 42 cnts[s] = cnts[last] 43 nbox[0] = last 44 } 45 return 0 46} 47 48// current concurrent count for ip (0 if absent). 49func cc_count(ips: *i64, cnts: *i64, nbox: *i64, ip: i64) -> i64 { 50 let s: i64 = cc_find(ips, nbox[0], ip) 51 if s < 0 { return 0 } 52 return cnts[s] 53}