ソースを参照

Perf/Refactor: faster ip version

SukkaW 1 年間 前
コミット
e19d7989c3

+ 1 - 1
Build/build-common.ts

@@ -147,7 +147,7 @@ async function transformRuleset(parentSpan: Span, sourcePath: string, relativePa
       if (res === $skip) return;
 
       const id = basename;
-      const type = relativePath.slice(0, -extname.length).split(path.sep)[0];
+      const type = relativePath.split(path.sep)[0];
 
       if (type !== 'ip' && type !== 'non_ip') {
         throw new TypeError(`Invalid type: ${type}`);

+ 7 - 5
Build/build-reject-ip-list.ts

@@ -3,11 +3,11 @@ import path from 'node:path';
 import { createReadlineInterfaceFromResponse, readFileIntoProcessedArray } from './lib/fetch-text-by-line';
 import { task } from './trace';
 import { SHARED_DESCRIPTION } from './constants/description';
-import { isProbablyIpv4, isProbablyIpv6 } from 'foxts/is-probably-ip';
 import { RulesetOutput } from './lib/create-file';
 import { SOURCE_DIR } from './constants/dir';
 import { $$fetch } from './lib/fetch-retry';
 import { fetchAssets } from './lib/fetch-assets';
+import { fastIpVersion } from './lib/misc';
 
 const BOGUS_NXDOMAIN_URL = 'https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/bogus-nxdomain.china.conf';
 const getBogusNxDomainIPsPromise: Promise<[ipv4: string[], ipv6: string[]]> = $$fetch(BOGUS_NXDOMAIN_URL).then(async (resp) => {
@@ -17,9 +17,10 @@ const getBogusNxDomainIPsPromise: Promise<[ipv4: string[], ipv6: string[]]> = $$
   for await (const line of createReadlineInterfaceFromResponse(resp, true)) {
     if (line.startsWith('bogus-nxdomain=')) {
       const ip = line.slice(15).trim();
-      if (isProbablyIpv4(ip)) {
+      const v = fastIpVersion(ip);
+      if (v === 4) {
         ipv4.push(ip);
-      } else if (isProbablyIpv6(ip)) {
+      } else if (v === 6) {
         ipv6.push(ip);
       }
     }
@@ -37,9 +38,10 @@ const BOTNET_FILTER_MIRROR_URL = [
 ];
 
 const getBotNetFilterIPsPromise: Promise<[ipv4: string[], ipv6: string[]]> = fetchAssets(BOTNET_FILTER_URL, BOTNET_FILTER_MIRROR_URL, true).then(arr => arr.reduce<[ipv4: string[], ipv6: string[]]>((acc, ip) => {
-  if (isProbablyIpv4(ip)) {
+  const v = fastIpVersion(ip);
+  if (v === 4) {
     acc[0].push(ip);
-  } else if (isProbablyIpv6(ip)) {
+  } else if (v === 6) {
     acc[1].push(ip);
   }
   return acc;

+ 4 - 5
Build/build-telegram-cidr.ts

@@ -1,11 +1,11 @@
 // @ts-check
 import { createReadlineInterfaceFromResponse } from './lib/fetch-text-by-line';
-import { isProbablyIpv4, isProbablyIpv6 } from 'foxts/is-probably-ip';
 import { task } from './trace';
 import { SHARED_DESCRIPTION } from './constants/description';
 import { createMemoizedPromise } from './lib/memo-promise';
 import { RulesetOutput } from './lib/create-file';
 import { $$fetch } from './lib/fetch-retry';
+import { fastIpVersion } from './lib/misc';
 
 export const getTelegramCIDRPromise = createMemoizedPromise(async () => {
   const resp = await $$fetch('https://core.telegram.org/resources/cidr.txt');
@@ -20,11 +20,10 @@ export const getTelegramCIDRPromise = createMemoizedPromise(async () => {
   const ipcidr6: string[] = [];
 
   for await (const cidr of createReadlineInterfaceFromResponse(resp, true)) {
-    const [subnet] = cidr.split('/');
-    if (isProbablyIpv4(subnet)) {
+    const v = fastIpVersion(cidr);
+    if (v === 4) {
       ipcidr.push(cidr);
-    }
-    if (isProbablyIpv6(subnet)) {
+    } else if (v === 6) {
       ipcidr6.push(cidr);
     }
   }

+ 1 - 1
Build/lib/cache-filesystem.ts

@@ -199,7 +199,7 @@ export const deserializeSet = (str: string) => new Set(str.split(separator));
 export const serializeArray = (arr: string[]) => fastStringArrayJoin(arr, separator);
 export const deserializeArray = (str: string) => str.split(separator);
 
-export const getFileContentHash = (filename: string) => simpleStringHash(fs.readFileSync(filename, 'utf-8'));
+const getFileContentHash = (filename: string) => simpleStringHash(fs.readFileSync(filename, 'utf-8'));
 export function createCacheKey(filename: string) {
   const fileHash = getFileContentHash(filename);
   return (key: string) => key + '$' + fileHash + '$';

+ 4 - 0
Build/lib/misc.ts

@@ -69,3 +69,7 @@ export function isDirectoryEmptySync(path: PathLike) {
     directoryHandle.closeSync();
   }
 }
+
+export function fastIpVersion(ip: string) {
+  return ip.includes(':') ? 6 : (ip.includes('.') ? 4 : 0);
+}

+ 20 - 12
Build/lib/rules/ruleset.ts

@@ -7,7 +7,8 @@ import type { SingboxSourceFormat } from '../singbox';
 import { RuleOutput } from './base';
 import picocolors from 'picocolors';
 import { normalizeDomain } from '../normalize-domain';
-import { isProbablyIpv4, isProbablyIpv6 } from 'foxts/is-probably-ip';
+import { isProbablyIpv4 } from 'foxts/is-probably-ip';
+import { fastIpVersion } from '../misc';
 
 type Preprocessed = [domain: string[], domainSuffix: string[], sortedDomainRules: string[]];
 
@@ -93,10 +94,11 @@ export class RulesetOutput extends RuleOutput<Preprocessed> {
       if (value.includes('/')) {
         return `SRC-IP-CIDR,${value}`;
       }
-      if (isProbablyIpv4(value)) {
+      const v = fastIpVersion(value);
+      if (v === 4) {
         return `SRC-IP-CIDR,${value}/32`;
       }
-      if (isProbablyIpv6(value)) {
+      if (v === 6) {
         return `SRC-IP-CIDR6,${value}/128`;
       }
       return '';
@@ -148,10 +150,14 @@ export class RulesetOutput extends RuleOutput<Preprocessed> {
         source_ip_cidr: [...this.sourceIpOrCidr].reduce<string[]>((acc, cur) => {
           if (cur.includes('/')) {
             acc.push(cur);
-          } else if (isProbablyIpv4(cur)) {
-            acc.push(cur + '/32');
-          } else if (isProbablyIpv6(cur)) {
-            acc.push(cur + '/128');
+          } else {
+            const v = fastIpVersion(cur);
+
+            if (v === 4) {
+              acc.push(cur + '/32');
+            } else if (v === 6) {
+              acc.push(cur + '/128');
+            }
           }
 
           return acc;
@@ -245,11 +251,13 @@ export class RulesetOutput extends RuleOutput<Preprocessed> {
 
     for (const i of urlRegexResults) {
       for (const processed of i.processed) {
-        if (normalizeDomain(
-          processed
-            .replaceAll('*', 'a')
-            .replaceAll('?', 'b')
-        )) {
+        if (
+          normalizeDomain(
+            processed
+              .replaceAll('*', 'a')
+              .replaceAll('?', 'b')
+          )
+        ) {
           parsed.push([i.origin, processed]);
         } else if (!isProbablyIpv4(processed)) {
           parsedFailures.push([i.origin, processed]);