code wiki / (root) / nx_ipfilter.nx

nx_ipfilter.nx source

↩ module page · 42 lines · 2581 B

1// nx_ipfilter.nx -- SOVEREIGN IP blocklist (BitTorrent ip-filter): reject known-bad / anti-P2P-monitor IP 2// ranges before we connect to them (worker) or accept them (seeder). Real privacy while WAN-seeding. Binary 3// blocklist format (ipfilter.bin): 8 bytes/entry = [start u32 LE][end u32 LE], inclusive IPv4 range. Linear 4// scan per check -- home-scale connection rate makes even 100k ranges <1ms + it's done once per peer. Load 5// ONCE (parent), children inherit the array via fork COW. license_tier: ORIGINAL depends: nx_syscalls 6import "nx_syscalls.nx" 7 8// dotted octets -> u32 host order 9func ipf_ip(a: i64, b: i64, c: i64, d: i64) -> i64 { return ((a&0xff)<<24)|((b&0xff)<<16)|((c&0xff)<<8)|(d&0xff) } 10// unpack a LE u32 from buf at off 11func ipf_u32le(buf: *u8, off: i64) -> i64 { return (buf[off] as i64)|((buf[off+1] as i64)<<8)|((buf[off+2] as i64)<<16)|((buf[off+3] as i64)<<24) } 12// pack a LE u32 into buf at off 13func ipf_put_u32le(buf: *u8, off: i64, v: i64) -> i64 { buf[off]=(v&0xff) as u8; buf[off+1]=((v>>8)&0xff) as u8; buf[off+2]=((v>>16)&0xff) as u8; buf[off+3]=((v>>24)&0xff) as u8; return off+4 } 14 15// Load ipfilter.bin into `arr` (i64 array, 2 slots/entry: arr[2i]=start, arr[2i+1]=end). Returns entry count 16// (0 if absent/empty -> filter is a safe no-op, never blocks). maxpairs caps the load. 17func ipf_load(path: *u8, arr: *i64, maxpairs: i64) -> i64 { 18 let fd: i64 = sys_openat_rd(path); if fd<0 { return 0 } 19 let cap: i64 = maxpairs*8 + 16 20 let buf: *u8 = sys_mmap(cap) 21 var tot: i64=0; var r: i64=1 22 while r>0 { if tot>=cap { r=0 } else { r=sys_read(fd, (((buf as i64)+tot) as *u8), cap-tot); if r>0 { tot=tot+r } } } 23 sys_close(fd) 24 let n: i64 = tot/8; var i: i64=0 25 while i<n { if i>=maxpairs { i=n } else { arr[2*i]=ipf_u32le(buf, 8*i); arr[2*i+1]=ipf_u32le(buf, 8*i+4); i=i+1 } } 26 if n>maxpairs { return maxpairs } 27 return n 28} 29// 1 if ip (u32 host order) falls in any blocked range, else 0. Unsigned compare via masking to 32 bits. 30func ipf_blocked(arr: *i64, count: i64, ip: i64) -> i64 { 31 let x: i64 = ip & 0xFFFFFFFF 32 var i: i64=0 33 while i<count { let s: i64=arr[2*i]&0xFFFFFFFF; let e: i64=arr[2*i+1]&0xFFFFFFFF; if x>=s { if x<=e { return 1 } } i=i+1 } 34 return 0 35} 36// convenience: load + check in one call (for callers that don't cache). path default handled by caller. 37func ipf_blocked_ip(path: *u8, ip: i64, maxpairs: i64) -> i64 { 38 let arr: *i64 = sys_mmap(maxpairs*16 + 64) as *i64 39 let c: i64 = ipf_load(path, arr, maxpairs) 40 if c<=0 { return 0 } 41 return ipf_blocked(arr, c, ip) 42}