From b91747e07fe1fb286fadfc523fb4d10f71efbe99 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Mon, 23 Sep 2024 02:58:34 +0800 Subject: [PATCH] Feat: merge IP CIDR in ruleset --- Build/build-internal-reverse-chn-cidr.ts | 19 +++++++------ Build/build-sgmodule-always-realip.ts | 2 +- Build/lib/rules/ip.ts | 24 +++++++++++++++-- Build/lib/rules/ruleset.ts | 34 ++++++++++++++++++++---- package.json | 2 +- pnpm-lock.yaml | 20 +++++--------- 6 files changed, 71 insertions(+), 30 deletions(-) diff --git a/Build/build-internal-reverse-chn-cidr.ts b/Build/build-internal-reverse-chn-cidr.ts index a1f28c25..ed1f6802 100644 --- a/Build/build-internal-reverse-chn-cidr.ts +++ b/Build/build-internal-reverse-chn-cidr.ts @@ -14,15 +14,18 @@ import { appendArrayInPlace } from './lib/append-array-in-place'; export const buildInternalReverseChnCIDR = task(require.main === module, __filename)(async () => { const [cidr] = await getChnCidrPromise(); - const reversedCidr = merge(appendArrayInPlace( - exclude( - ['0.0.0.0/0'], - RESERVED_IPV4_CIDR.concat(cidr), - true + const reversedCidr = merge( + appendArrayInPlace( + exclude( + ['0.0.0.0/0'], + RESERVED_IPV4_CIDR.concat(cidr), + true + ), + // https://github.com/misakaio/chnroutes2/issues/25 + NON_CN_CIDR_INCLUDED_IN_CHNROUTE ), - // https://github.com/misakaio/chnroutes2/issues/25 - NON_CN_CIDR_INCLUDED_IN_CHNROUTE - )); + true + ); const outputFile = path.join(OUTPUT_INTERNAL_DIR, 'reversed-chn-cidr.txt'); await mkdirp(OUTPUT_INTERNAL_DIR); diff --git a/Build/build-sgmodule-always-realip.ts b/Build/build-sgmodule-always-realip.ts index 46db005b..19996115 100644 --- a/Build/build-sgmodule-always-realip.ts +++ b/Build/build-sgmodule-always-realip.ts @@ -49,7 +49,6 @@ export const buildAlwaysRealIPModule = task(require.main === module, __filename) // Intranet, Router Setup, and mant more const dataset = [Object.entries(DIRECTS), Object.entries(LANS)]; const surge = dataset.flatMap(data => data.flatMap(([, { domains }]) => domains.flatMap((domain) => [`*.${domain}`, domain]))); - const clash = ; return Promise.all([ compareAndWriteFile( @@ -69,6 +68,7 @@ export const buildAlwaysRealIPModule = task(require.main === module, __filename) { dns: { 'fake-ip-filter': appendArrayInPlace( + /** clash */ dataset.flatMap(data => data.flatMap(([, { domains }]) => domains.map((domain) => `+.${domain}`))), HOSTNAMES ) diff --git a/Build/lib/rules/ip.ts b/Build/lib/rules/ip.ts index e925c588..979eebce 100644 --- a/Build/lib/rules/ip.ts +++ b/Build/lib/rules/ip.ts @@ -1,4 +1,5 @@ import type { Span } from '../../trace'; +import { appendArrayInPlace } from '../append-array-in-place'; import { appendArrayFromSet } from '../misc'; import type { SingboxSourceFormat } from '../singbox'; import { RuleOutput } from './base'; @@ -15,7 +16,18 @@ export class IPListOutput extends RuleOutput { private $merged: string[] | null = null; get merged() { if (!this.$merged) { - this.$merged = merge(appendArrayFromSet([], [this.ipcidr, this.ipcidr6])); + const results: string[] = []; + appendArrayInPlace( + results, + merge( + appendArrayInPlace(Array.from(this.ipcidrNoResolve), Array.from(this.ipcidr)), + true + ) + ); + appendArrayFromSet(results, this.ipcidr6NoResolve); + appendArrayFromSet(results, this.ipcidr6); + + this.$merged = results; } return this.$merged; } @@ -26,7 +38,15 @@ export class IPListOutput extends RuleOutput { if (!this.$surge) { const results: string[] = ['DOMAIN,this_ruleset_is_made_by_sukkaw.ruleset.skk.moe']; - appendArrayFromSet(results, this.ipcidr, i => `IP-CIDR,${i}`); + appendArrayInPlace( + results, + merge(Array.from(this.ipcidrNoResolve)).map(i => `IP-CIDR,${i},no-resolve`, true) + ); + appendArrayFromSet(results, this.ipcidr6NoResolve, i => `IP-CIDR6,${i},no-resolve`); + appendArrayInPlace( + results, + merge(Array.from(this.ipcidr)).map(i => `IP-CIDR,${i}`, true) + ); appendArrayFromSet(results, this.ipcidr6, i => `IP-CIDR6,${i}`); this.$surge = results; diff --git a/Build/lib/rules/ruleset.ts b/Build/lib/rules/ruleset.ts index 6b36fede..a7870eab 100644 --- a/Build/lib/rules/ruleset.ts +++ b/Build/lib/rules/ruleset.ts @@ -1,3 +1,4 @@ +import { merge } from 'fast-cidr-tools'; import type { Span } from '../../trace'; import createKeywordFilter from '../aho-corasick'; import { appendArrayInPlace } from '../append-array-in-place'; @@ -54,12 +55,18 @@ export class RulesetOutput extends RuleOutput { appendArrayFromSet(results, this.urlRegex, i => `URL-REGEX,${i}`); - appendArrayFromSet(results, this.ipcidrNoResolve, i => `IP-CIDR,${i},no-resolve`); + appendArrayInPlace( + results, + merge(Array.from(this.ipcidrNoResolve)).map(i => `IP-CIDR,${i},no-resolve`, true) + ); appendArrayFromSet(results, this.ipcidr6NoResolve, i => `IP-CIDR6,${i},no-resolve`); appendArrayFromSet(results, this.ipasnNoResolve, i => `IP-ASN,${i},no-resolve`); appendArrayFromSet(results, this.groipNoResolve, i => `GEOIP,${i},no-resolve`); - appendArrayFromSet(results, this.ipcidr, i => `IP-CIDR,${i}`); + appendArrayInPlace( + results, + merge(Array.from(this.ipcidr)).map(i => `IP-CIDR,${i}`, true) + ); appendArrayFromSet(results, this.ipcidr6, i => `IP-CIDR6,${i}`); appendArrayFromSet(results, this.ipasn, i => `IP-ASN,${i}`); appendArrayFromSet(results, this.geoip, i => `GEOIP,${i}`); @@ -80,12 +87,18 @@ export class RulesetOutput extends RuleOutput { // appendArrayInPlace(results, this.otherRules); - appendArrayFromSet(results, this.ipcidrNoResolve, i => `IP-CIDR,${i},no-resolve`); + appendArrayInPlace( + results, + merge(Array.from(this.ipcidrNoResolve)).map(i => `IP-CIDR,${i},no-resolve`, true) + ); appendArrayFromSet(results, this.ipcidr6NoResolve, i => `IP-CIDR6,${i},no-resolve`); appendArrayFromSet(results, this.ipasnNoResolve, i => `IP-ASN,${i},no-resolve`); appendArrayFromSet(results, this.groipNoResolve, i => `GEOIP,${i},no-resolve`); - appendArrayFromSet(results, this.ipcidr, i => `IP-CIDR,${i}`); + appendArrayInPlace( + results, + merge(Array.from(this.ipcidr)).map(i => `IP-CIDR,${i}`, true) + ); appendArrayFromSet(results, this.ipcidr6, i => `IP-CIDR6,${i}`); appendArrayFromSet(results, this.ipasn, i => `IP-ASN,${i}`); appendArrayFromSet(results, this.geoip, i => `GEOIP,${i}`); @@ -94,6 +107,17 @@ export class RulesetOutput extends RuleOutput { } singbox(): string[] { + const ip_cidr: string[] = []; + appendArrayInPlace( + ip_cidr, + merge( + appendArrayInPlace(Array.from(this.ipcidrNoResolve), Array.from(this.ipcidr)), + true + ) + ); + appendArrayFromSet(ip_cidr, this.ipcidr6NoResolve); + appendArrayFromSet(ip_cidr, this.ipcidr6); + const singbox: SingboxSourceFormat = { version: 2, rules: [{ @@ -101,7 +125,7 @@ export class RulesetOutput extends RuleOutput { domain_suffix: this.computed()[1], domain_keyword: Array.from(this.domainKeywords), domain_regex: Array.from(this.domainWildcard).map(RuleOutput.domainWildCardToRegex), - ip_cidr: appendArrayFromSet([], [this.ipcidr, this.ipcidrNoResolve, this.ipcidr6, this.ipcidr6NoResolve]), + ip_cidr, process_name: Array.from(this.processName), process_path: Array.from(this.processPath) }] diff --git a/package.json b/package.json index f900ab84..fa4b876d 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "better-sqlite3": "^11.3.0", "ci-info": "^4.0.0", "csv-parse": "^5.5.6", - "fast-cidr-tools": "^0.2.5", + "fast-cidr-tools": "^0.3.0", "fdir": "^6.3.0", "foxact": "^0.2.38", "hash-wasm": "^4.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6974b49b..ca7ca07b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,8 +33,8 @@ importers: specifier: ^5.5.6 version: 5.5.6 fast-cidr-tools: - specifier: ^0.2.5 - version: 0.2.5 + specifier: ^0.3.0 + version: 0.3.0 fdir: specifier: ^6.3.0 version: 6.3.0(picomatch@4.0.2) @@ -488,10 +488,6 @@ packages: typescript: optional: true - '@typescript-eslint/types@8.0.0-alpha.36': - resolution: {integrity: sha512-D+w5uE8Y83K/P5VQZyKKi4pwTL2YkWOwtQOVJQI38Rp8f3pmY+Jmcps3wkSFSJK8wifTlvoHwwIBf1FsdCW/EA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.6.0': resolution: {integrity: sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -880,8 +876,8 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - fast-cidr-tools@0.2.5: - resolution: {integrity: sha512-7/NO0T7mMlpOzm9b5wMhqZn6VO4CvQ0tQ8X0Nw/6uE74GRN+qV6lBZzlHlbtPAAutKqE3jThAL6WbON+7hNz1g==} + fast-cidr-tools@0.3.0: + resolution: {integrity: sha512-KgqVgJWV2/tYZaLc4tbV1rPgx6R79SlkwZ7a2V6n3yShZZT5dCIc4R7CeK4mSJoYV916JXjR78KGGWRDWFuNgw==} engines: {node: '>=16'} fast-deep-equal@3.1.3: @@ -1930,7 +1926,7 @@ snapshots: '@typescript-eslint/scope-manager@8.6.0': dependencies: - '@typescript-eslint/types': 8.0.0-alpha.36 + '@typescript-eslint/types': 8.6.0 '@typescript-eslint/visitor-keys': 8.6.0 '@typescript-eslint/type-utils@8.6.0(eslint@9.10.0)(typescript@5.6.2)': @@ -1945,8 +1941,6 @@ snapshots: - eslint - supports-color - '@typescript-eslint/types@8.0.0-alpha.36': {} - '@typescript-eslint/types@8.6.0': {} '@typescript-eslint/typescript-estree@8.6.0(typescript@5.6.2)': @@ -1977,7 +1971,7 @@ snapshots: '@typescript-eslint/visitor-keys@8.6.0': dependencies: - '@typescript-eslint/types': 8.0.0-alpha.36 + '@typescript-eslint/types': 8.6.0 eslint-visitor-keys: 3.4.3 acorn-jsx@5.3.2(acorn@8.12.1): @@ -2427,7 +2421,7 @@ snapshots: expand-template@2.0.3: {} - fast-cidr-tools@0.2.5: {} + fast-cidr-tools@0.3.0: {} fast-deep-equal@3.1.3: {}