better code: unified code for net masks

Massimo Melina committed Mar 31, 2023 at 23:10 UTC a6a766e110879e4fbb20a19b23569986337d7608
2 files changed +12 -21
src/block.ts
+4 -19
@@ -2,35 +2,20 @@
2
3 import { defineConfig } from './config'
4 import { getConnections, normalizeIp } from './connections'
5 -import { onlyTruthy, with_ } from './misc'
6 -import cidr from 'cidr-tools'
7 -import _ from 'lodash'
5 +import { makeNetMatcher, onlyTruthy } from './misc'
6 import { Socket } from 'net'
7
8 type BlockFun = (x: string) => boolean
9 let blockFunctions: BlockFun[] = [] // "compiled" versions of the rules in config.block
10
11 defineConfig<string[]>('block', []).sub(rules => {
14 - compileBlock(rules)
12 + blockFunctions = !Array.isArray(rules) ? []
13 + : onlyTruthy(rules.map((rule: any) => rule?.ip && makeNetMatcher(rule.ip)))
14 + // reapply new block to existing connections
15 for (const { socket, ip } of getConnections())
16 applyBlock(socket, ip)
17 })
18
19 -function compileBlock(rules: any) {
20 - blockFunctions = !Array.isArray(rules) ? []
21 - : onlyTruthy(rules.map(rule => !rule ? null
22 - : with_(rule.ip, ip => typeof ip !== 'string' ? null
23 - : ip.includes('/') ? x => cidr.contains(ip, x)
24 - : ip.includes('*') ? with_(ipMask2regExp(ip), re => x => re.test(x) )
25 - : x => x === ip
26 - )
27 - ))
28 -
29 - function ipMask2regExp(ipMask: string) {
30 - return new RegExp(_.escapeRegExp(ipMask).replace(/\\\*/g, '.*'))
31 - }
32 -}
33 -
19 export function applyBlock(socket: Socket, ip=normalizeIp(socket.remoteAddress||'')) {
20 if (ip && blockFunctions.find(rule => rule(ip)))
21 return socket.destroy()
src/misc.ts
+8 -2
@@ -11,7 +11,8 @@ export * from './util-generators'
11 export * from './util-files'
12 import debounceAsync from './debounceAsync'
13 import { Readable } from 'stream'
14 -import { isMatch } from 'micromatch'
14 +import { isMatch, matcher } from 'micromatch'
15 +import cidr from 'cidr-tools'
16 export { debounceAsync }
17
18 export type Callback<IN=void, OUT=void> = (x:IN) => OUT
@@ -175,7 +176,12 @@ export function isLocalHost(c: Connection | Koa.Context) {
176 export function matchesNet(ip: Koa.Context | string, mask: string, emptyMaskReturns=false) {
177 if (typeof ip !== 'string')
178 ip = ip.ip
178 - return matches(ip, mask, emptyMaskReturns)
179 + return mask ? makeNetMatcher(mask)(ip) : emptyMaskReturns
180 +}
181 +
182 +export function makeNetMatcher(mask: string) {
183 + return mask.includes('/') ? (ip: string) => cidr.contains(mask, ip)
184 + : matcher(mask)
185 }
186
187 export function matches(s: string, mask: string, emptyMaskReturns=false) {