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) {