Perf/Refactor: faster ip version

This commit is contained in:
SukkaW 2025-01-22 20:04:41 +08:00
parent 07419a7942
commit e19d7989c3
6 changed files with 37 additions and 24 deletions

View File

@ -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}`);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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 + '$';

View File

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

View File

@ -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]);