New Domestic CDN Hosts Output Support

This commit is contained in:
SukkaW
2026-09-23 02:37:40 +08:00
parent 1baae2ff74
commit 8b5e39525b
7 changed files with 122 additions and 32 deletions

View File

@@ -1,6 +1,7 @@
// @ts-check
import path from 'node:path';
import { DOMESTICS, DOH_BOOTSTRAP, AdGuardHomeDNSMapping } from '../Source/non_ip/domestic';
import { DOMESTIC_CDN } from '../Source/non_ip/domestic_cdn';
import { DIRECTS, HOSTS, LAN } from '../Source/non_ip/direct';
import type { DNSMapping } from '../Source/non_ip/direct';
import { fetchRemoteTextLines, readFileIntoProcessedArray } from './lib/fetch-text-by-line';
@@ -53,6 +54,17 @@ export function createGetDnsMappingRule(allowWildcard: boolean) {
};
}
export const getDomesticCdnDomainsRulesetPromise = once(async () => {
const domesticCdn = await readFileIntoProcessedArray(path.join(SOURCE_DIR, 'non_ip/domestic_cdn.conf'));
const getDnsMappingRuleWithWildcard = createGetDnsMappingRule(true);
Object.values(DOMESTIC_CDN).forEach(({ domains }) => {
appendArrayInPlace(domesticCdn, domains.flatMap(getDnsMappingRuleWithWildcard));
});
return domesticCdn;
});
export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
const domestics = await readFileIntoProcessedArray(path.join(SOURCE_DIR, 'non_ip/domestic.conf'));
const directs = await readFileIntoProcessedArray(path.resolve(SOURCE_DIR, 'non_ip/direct.conf'));
@@ -66,6 +78,9 @@ export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
});
});
// Keep legacy subscriptions inclusive of the CDN exceptions.
appendArrayInPlace(domestics, await getDomesticCdnDomainsRulesetPromise());
Object.values(DIRECTS).forEach(({ domains }) => {
appendArrayInPlace(directs, domains.flatMap(getDnsMappingRuleWithWildcard));
});
@@ -81,8 +96,16 @@ export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
export const buildDomesticRuleset = task(require.main === module, __filename)(async (span) => {
const [domestics, directs, lans] = await getDomesticAndDirectDomainsRulesetPromise();
const domesticCdn = await getDomesticCdnDomainsRulesetPromise();
const dataset: Array<[name: string, DNSMapping]> = ([DOH_BOOTSTRAP, DOMESTICS, DIRECTS, LAN, HOSTS] as const).flatMap(Object.entries);
// Preserve existing provider IDs, and namespace CDN providers so the same
// provider can appear in both sources without overwriting its ruleset or DNS policy.
const domesticMappings = Object.entries(DOMESTIC_CDN).reduce<Record<string, DNSMapping>>((mappings, [name, mapping]) => {
mappings[`DOMESTIC_CDN_${name}`] = mapping;
return mappings;
}, { ...DOMESTICS });
const dataset: Array<[name: string, mapping: DNSMapping]> = ([DOH_BOOTSTRAP, domesticMappings, DIRECTS, LAN, HOSTS] as const).flatMap(Object.entries);
return Promise.all([
new RulesetOutput(span, 'domestic', 'non_ip')
@@ -94,6 +117,17 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as
)
.addFromRuleset(domestics)
.write(),
new RulesetOutput(span, 'domestic_cdn', 'non_ip')
.withTitle('Sukka\'s Ruleset - Domestic CDN Domains')
.appendDescription(
SHARED_DESCRIPTION,
'',
'This file contains CDN domains of domestic services that should use DIRECT both in China and abroad.',
'Place this ruleset before domestic when routing other domestic traffic back to China.',
'All entries are also included in the domestic ruleset.'
)
.addFromRuleset(domesticCdn)
.write(),
new RulesetOutput(span, 'direct', 'non_ip')
.withTitle('Sukka\'s Ruleset - Direct Rules')
.appendDescription(
@@ -328,7 +362,7 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as
'https://doh.pub/dns-query',
'https://dns.alidns.com/dns-query',
'[//]udp://10.10.1.1:53',
...(([DOMESTICS, DIRECTS, LAN, HOSTS] as const).flatMap(Object.values) as DNSMapping[]).flatMap(({ domains, dns: _dns }) => domains.flatMap((domain) => {
...(([domesticMappings, DIRECTS, LAN, HOSTS] as const).flatMap(Object.values) as DNSMapping[]).flatMap(({ domains, dns: _dns }) => domains.flatMap((domain) => {
if (!_dns) {
return [];
}

View File

@@ -4,6 +4,7 @@ import { compareAndWriteFile } from './lib/create-file';
import { DIRECTS, LAN } from '../Source/non_ip/direct';
import type { DNSMapping } from '../Source/non_ip/direct';
import { DOMESTICS, DOH_BOOTSTRAP } from '../Source/non_ip/domestic';
import { DOMESTIC_CDN } from '../Source/non_ip/domestic_cdn';
import * as yaml from 'yaml';
import { OUTPUT_INTERNAL_DIR, OUTPUT_MODULES_DIR } from './constants/dir';
import { appendArrayInPlace } from 'foxts/append-array-in-place';
@@ -61,7 +62,7 @@ export const buildAlwaysRealIPModule = task(require.main === module, __filename)
]);
// Intranet, Router Setup, and mant more
const dataset = [DIRECTS, LAN, DOMESTICS, DOH_BOOTSTRAP].reduce<DNSMapping[]>((acc, item) => {
const dataset = [DIRECTS, LAN, DOMESTICS, DOMESTIC_CDN, DOH_BOOTSTRAP].reduce<DNSMapping[]>((acc, item) => {
Object.values(item).forEach((i: DNSMapping) => {
if (i.realip) {
acc.push(i);

View File

@@ -8,6 +8,7 @@ import { HostnameSmolTrie } from 'hntrie/smol';
import { domainToASCII } from 'node:url';
import tldts from 'tldts-experimental';
import { DOMESTICS } from '../Source/non_ip/domestic';
import { DOMESTIC_CDN } from '../Source/non_ip/domestic_cdn';
export async function parseDomesticList() {
const allChinaDomains = new Set<string>(await parseFelixDnsmasqFromResp(await $$fetch('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf')));
@@ -27,6 +28,10 @@ export async function parseDomesticList() {
const callback = (domain: string, includeAllSubdomain: boolean) => resultTrie.whitelist(includeAllSubdomain ? '.' + domain : domain);
// await Promise.all([
await runAgainstSourceFile(
path.resolve(SOURCE_DIR, 'non_ip/domestic_cdn.conf'),
callback
);
await runAgainstSourceFile(
path.resolve(SOURCE_DIR, 'non_ip/domestic.conf'),
callback
@@ -36,7 +41,7 @@ export async function parseDomesticList() {
callback
);
Object.values(DOMESTICS).forEach(domestic => {
[DOMESTICS, DOMESTIC_CDN].flatMap(item => Object.values(item)).forEach(domestic => {
domestic.domains.forEach(domain => {
switch (domain[0]) {
case '+':