mirror of
https://github.com/therootcompany/golib.git
synced 2026-11-04 15:05:00 +00:00
IPv4 host + CIDR membership testing backed by sorted /32 binary search and a linear scan of CIDR ranges. CSV/text loader with bounded reads (maxBytes is required so callers pick a limit appropriate to their input source — 1 KB allowlists through 100+ MB threat feeds). Returns errors for unparseable IPs so callers can decide fail-open vs fail-closed; partial cohorts are returned alongside parse errors.
ipcohort
A memory-efficient, fast IP cohort checker for blacklists, whitelists, and ad cohorts.
- 4 bytes per /32 host, 5 bytes per CIDR range (8 with alignment padding)
- O(log n) binary search across both hosts and CIDR ranges
- immutable cohorts — callers swap via
atomic.Pointerfor lock-free reads - requires CIDR sources to be an anti-chain (no entry contained in another; a /8 supersedes any /24 inside it). Most curated blocklists already ship pre-normalized this way.
Example
Check if an IP address belongs to a cohort (such as a blacklist):
cohort, err := ipcohort.LoadFile("/srv/data/inbound.txt")
if err != nil {
log.Fatalf("load: %v", err)
}
blocked, err := cohort.Contains("92.255.85.72")
if err != nil {
log.Fatalf("parse: %v", err)
}
if blocked {
fmt.Println("BLOCKED")
os.Exit(1)
}
fmt.Println("allowed")
Cohort.Contains(string) parses the address each call and returns an error
on unparseable input — callers decide fail-open vs fail-closed. If you
already have a netip.Addr (e.g. from netip.ParseAddr on a request peer),
use Cohort.ContainsAddr(netip.Addr) to skip the parse and the error.