mirror of
https://github.com/SukkaW/Surge.git
synced 2025-12-15 18:50:34 +08:00
Chore: make sure random DoH Servers are different
This commit is contained in:
parent
26eb05572f
commit
65558592cb
@ -1,6 +1,7 @@
|
|||||||
import tldts from 'tldts-experimental';
|
import tldts from 'tldts-experimental';
|
||||||
import { looseTldtsOpt } from '../constants/loose-tldts-opt';
|
import { looseTldtsOpt } from '../constants/loose-tldts-opt';
|
||||||
import picocolors from 'picocolors';
|
import picocolors from 'picocolors';
|
||||||
|
import { pickRandom, pickOne } from 'foxts/pick-random';
|
||||||
|
|
||||||
import DNS2 from 'dns2';
|
import DNS2 from 'dns2';
|
||||||
import asyncRetry from 'async-retry';
|
import asyncRetry from 'async-retry';
|
||||||
@ -82,32 +83,27 @@ const domesticDohServers: Array<[string, DNS2.DnsResolver]> = ([
|
|||||||
})
|
})
|
||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
function createResolve(server: Array<[string, DNS2.DnsResolver]>): DNS2.DnsResolver<DnsResponse> {
|
async function $resolve(name: string, type: DNS2.PacketQuestion, server: [string, DNS2.DnsResolver]) {
|
||||||
return async (...args) => {
|
try {
|
||||||
try {
|
return await asyncRetry(async () => {
|
||||||
return await asyncRetry(async () => {
|
const [dohServer, dohClient] = server;
|
||||||
const [dohServer, dohClient] = server[Math.floor(Math.random() * server.length)];
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return {
|
return {
|
||||||
...await dohClient(...args),
|
...await dohClient(name, type),
|
||||||
dns: dohServer
|
dns: dohServer
|
||||||
} satisfies DnsResponse;
|
} satisfies DnsResponse;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// console.error(e);
|
// console.error(e);
|
||||||
throw new DnsError((e as Error).message, dohServer);
|
throw new DnsError((e as Error).message, dohServer);
|
||||||
}
|
}
|
||||||
}, { retries: 5 });
|
}, { retries: 5 });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('[doh error]', ...args, e);
|
console.log('[doh error]', name, type, e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const resolve = createResolve(dohServers);
|
|
||||||
const domesticResolve = createResolve(domesticDohServers);
|
|
||||||
|
|
||||||
async function getWhois(domain: string) {
|
async function getWhois(domain: string) {
|
||||||
return asyncRetry(() => whoiser.domain(domain, { raw: true }), { retries: 5 });
|
return asyncRetry(() => whoiser.domain(domain, { raw: true }), { retries: 5 });
|
||||||
}
|
}
|
||||||
@ -147,9 +143,10 @@ export async function isDomainAlive(domain: string, isSuffix: boolean): Promise<
|
|||||||
const aaaaDns: string[] = [];
|
const aaaaDns: string[] = [];
|
||||||
|
|
||||||
// test 2 times before make sure record is empty
|
// test 2 times before make sure record is empty
|
||||||
|
const servers = pickRandom(dohServers, 3);
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i++) {
|
||||||
// eslint-disable-next-line no-await-in-loop -- sequential
|
// eslint-disable-next-line no-await-in-loop -- sequential
|
||||||
const aRecords = (await resolve($domain, 'A'));
|
const aRecords = (await $resolve($domain, 'A', servers[i]));
|
||||||
if (aRecords.answers.length > 0) {
|
if (aRecords.answers.length > 0) {
|
||||||
return onDomainAlive(domain);
|
return onDomainAlive(domain);
|
||||||
}
|
}
|
||||||
@ -158,7 +155,7 @@ export async function isDomainAlive(domain: string, isSuffix: boolean): Promise<
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i++) {
|
||||||
// eslint-disable-next-line no-await-in-loop -- sequential
|
// eslint-disable-next-line no-await-in-loop -- sequential
|
||||||
const aaaaRecords = (await resolve($domain, 'AAAA'));
|
const aaaaRecords = (await $resolve($domain, 'AAAA', servers[i]));
|
||||||
if (aaaaRecords.answers.length > 0) {
|
if (aaaaRecords.answers.length > 0) {
|
||||||
return onDomainAlive(domain);
|
return onDomainAlive(domain);
|
||||||
}
|
}
|
||||||
@ -167,13 +164,13 @@ export async function isDomainAlive(domain: string, isSuffix: boolean): Promise<
|
|||||||
}
|
}
|
||||||
|
|
||||||
// only then, let's test once with domesticDohServers
|
// only then, let's test once with domesticDohServers
|
||||||
const aRecords = (await domesticResolve($domain, 'A'));
|
const aRecords = (await $resolve($domain, 'A', pickOne(domesticDohServers)));
|
||||||
if (aRecords.answers.length > 0) {
|
if (aRecords.answers.length > 0) {
|
||||||
return onDomainAlive(domain);
|
return onDomainAlive(domain);
|
||||||
}
|
}
|
||||||
aDns.push(aRecords.dns);
|
aDns.push(aRecords.dns);
|
||||||
|
|
||||||
const aaaaRecords = (await domesticResolve($domain, 'AAAA'));
|
const aaaaRecords = (await $resolve($domain, 'AAAA', pickOne(domesticDohServers)));
|
||||||
if (aaaaRecords.answers.length > 0) {
|
if (aaaaRecords.answers.length > 0) {
|
||||||
return onDomainAlive(domain);
|
return onDomainAlive(domain);
|
||||||
}
|
}
|
||||||
@ -194,7 +191,7 @@ async function isApexDomainAlive(apexDomain: string): Promise<[string, boolean]>
|
|||||||
if (apexDomainNsResolvePromiseMap.has(apexDomain)) {
|
if (apexDomainNsResolvePromiseMap.has(apexDomain)) {
|
||||||
resp = await apexDomainNsResolvePromiseMap.get(apexDomain)!;
|
resp = await apexDomainNsResolvePromiseMap.get(apexDomain)!;
|
||||||
} else {
|
} else {
|
||||||
const promise = resolve(apexDomain, 'NS');
|
const promise = $resolve(apexDomain, 'NS', pickOne(dohServers));
|
||||||
apexDomainNsResolvePromiseMap.set(apexDomain, promise);
|
apexDomainNsResolvePromiseMap.set(apexDomain, promise);
|
||||||
resp = await promise;
|
resp = await promise;
|
||||||
}
|
}
|
||||||
|
|||||||
7
Build/mod.d.ts
vendored
7
Build/mod.d.ts
vendored
@ -1,9 +1,9 @@
|
|||||||
import 'dns2';
|
import 'dns2';
|
||||||
|
|
||||||
declare module 'dns2' {
|
declare module 'dns2' {
|
||||||
import DNS from 'dns2';
|
import DNS2 from 'dns2';
|
||||||
|
|
||||||
declare namespace DNS {
|
declare namespace DNS2 {
|
||||||
interface DoHClientOption {
|
interface DoHClientOption {
|
||||||
/** @example dns.google.com */
|
/** @example dns.google.com */
|
||||||
dns: string,
|
dns: string,
|
||||||
@ -13,6 +13,7 @@ declare module 'dns2' {
|
|||||||
get?: (url: string) => any
|
get?: (url: string) => any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type PacketQuestion = keyof typeof Packet.TYPE;
|
||||||
export type DnsResolver<T = DnsResponse> = (name: string, type: PacketQuestion) => Promise<T>;
|
export type DnsResolver<T = DnsResponse> = (name: string, type: PacketQuestion) => Promise<T>;
|
||||||
|
|
||||||
declare function DOHClient(opt: DoHClientOption): DnsResolver;
|
declare function DOHClient(opt: DoHClientOption): DnsResolver;
|
||||||
@ -20,5 +21,5 @@ declare module 'dns2' {
|
|||||||
export type $DnsResponse = DnsResponse;
|
export type $DnsResponse = DnsResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
export = DNS;
|
export = DNS2;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
"fast-cidr-tools": "^0.3.1",
|
"fast-cidr-tools": "^0.3.1",
|
||||||
"fast-fifo": "^1.3.2",
|
"fast-fifo": "^1.3.2",
|
||||||
"fdir": "^6.4.3",
|
"fdir": "^6.4.3",
|
||||||
"foxts": "^1.2.0",
|
"foxts": "^1.3.0",
|
||||||
"hash-wasm": "^4.12.0",
|
"hash-wasm": "^4.12.0",
|
||||||
"json-stringify-pretty-compact": "3.0.0",
|
"json-stringify-pretty-compact": "3.0.0",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
|
|||||||
17
pnpm-lock.yaml
generated
17
pnpm-lock.yaml
generated
@ -53,8 +53,8 @@ importers:
|
|||||||
specifier: ^6.4.3
|
specifier: ^6.4.3
|
||||||
version: 6.4.3(picomatch@4.0.2)
|
version: 6.4.3(picomatch@4.0.2)
|
||||||
foxts:
|
foxts:
|
||||||
specifier: ^1.2.0
|
specifier: ^1.3.0
|
||||||
version: 1.2.0
|
version: 1.3.0
|
||||||
hash-wasm:
|
hash-wasm:
|
||||||
specifier: ^4.12.0
|
specifier: ^4.12.0
|
||||||
version: 4.12.0
|
version: 4.12.0
|
||||||
@ -1094,8 +1094,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
|
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
foxts@1.2.0:
|
foxts@1.3.0:
|
||||||
resolution: {integrity: sha512-GQp91VeREH/fglR4KY5479nATcqnDLBWqEMhPFCD8qd48hA7DB9TD5Q9czC54j9ez9WGHjjTcbjokNWZsSI2Nw==}
|
resolution: {integrity: sha512-TaqRKSTN6uQNFXma3jZQfH2fBqNoePlHJtEGWuaFGWI0lSpe/7UnugEpcZzKy2m5J8EVKdxJl+uPZbHGFNLntQ==}
|
||||||
|
|
||||||
fs-constants@1.0.0:
|
fs-constants@1.0.0:
|
||||||
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
||||||
@ -1647,6 +1647,9 @@ packages:
|
|||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
uncrypto@0.1.3:
|
||||||
|
resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
|
||||||
|
|
||||||
undici-cache-store-better-sqlite3@0.1.1:
|
undici-cache-store-better-sqlite3@0.1.1:
|
||||||
resolution: {integrity: sha512-F/PxGx+QY3oScnFQ/YGbN7AYtqKLTzps0izFi8LddDaobso3SYXyQORuPcnUd2JbqpdxmLLkvS2zSvG6VPPMpw==}
|
resolution: {integrity: sha512-F/PxGx+QY3oScnFQ/YGbN7AYtqKLTzps0izFi8LddDaobso3SYXyQORuPcnUd2JbqpdxmLLkvS2zSvG6VPPMpw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2780,7 +2783,9 @@ snapshots:
|
|||||||
cross-spawn: 7.0.6
|
cross-spawn: 7.0.6
|
||||||
signal-exit: 4.1.0
|
signal-exit: 4.1.0
|
||||||
|
|
||||||
foxts@1.2.0: {}
|
foxts@1.3.0:
|
||||||
|
dependencies:
|
||||||
|
uncrypto: 0.1.3
|
||||||
|
|
||||||
fs-constants@1.0.0: {}
|
fs-constants@1.0.0: {}
|
||||||
|
|
||||||
@ -3349,6 +3354,8 @@ snapshots:
|
|||||||
|
|
||||||
typescript@5.7.3: {}
|
typescript@5.7.3: {}
|
||||||
|
|
||||||
|
uncrypto@0.1.3: {}
|
||||||
|
|
||||||
undici-cache-store-better-sqlite3@0.1.1(undici@7.3.0(patch_hash=594ba65c371ae78d02b8402fbad8cdc3617510f9ee2390a258e0ce5742a93926)):
|
undici-cache-store-better-sqlite3@0.1.1(undici@7.3.0(patch_hash=594ba65c371ae78d02b8402fbad8cdc3617510f9ee2390a258e0ce5742a93926)):
|
||||||
dependencies:
|
dependencies:
|
||||||
better-sqlite3: 11.8.1
|
better-sqlite3: 11.8.1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user