From 2b3b9177e5b44b0684c8005e6a2dec8b3aba19d3 Mon Sep 17 00:00:00 2001 From: xream Date: Thu, 20 Jun 2024 11:28:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9F=9F=E5=90=8D=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20`=5Fresolved=5Fips`=20=E4=B8=BA=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=87=BA=E7=9A=84=E6=89=80=E6=9C=89=20IP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package.json | 2 +- .../src/core/proxy-utils/processors/index.js | 48 ++++++++++++++----- scripts/demo.js | 9 +++- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/backend/package.json b/backend/package.json index 2b7be29..1d8146d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.341", + "version": "2.14.342", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { diff --git a/backend/src/core/proxy-utils/processors/index.js b/backend/src/core/proxy-utils/processors/index.js index a96135a..5b09ced 100644 --- a/backend/src/core/proxy-utils/processors/index.js +++ b/backend/src/core/proxy-utils/processors/index.js @@ -406,10 +406,13 @@ const DOMAIN_RESOLVERS = { throw new Error(`Status is ${body['Status']}`); } const answers = body['Answer']; - if (answers.length === 0) { + if (!Array.isArray(answers) || answers.length === 0) { + throw new Error('No answers'); + } + const result = answers.map((i) => i?.data).filter((i) => i); + if (result.length === 0) { throw new Error('No answers'); } - const result = answers[answers.length - 1].data; resourceCache.set(id, result); return result; }, @@ -429,7 +432,13 @@ const DOMAIN_RESOLVERS = { if (body['status'] !== 'success') { throw new Error(`Status is ${body['status']}`); } - const result = body.query; + if (!body.query || body.query === 0) { + throw new Error('No answers'); + } + const result = [body.query]; + if (result.length === 0) { + throw new Error('No answers'); + } resourceCache.set(id, result); return result; }, @@ -450,10 +459,13 @@ const DOMAIN_RESOLVERS = { throw new Error(`Status is ${body['Status']}`); } const answers = body['Answer']; - if (answers.length === 0) { + if (!Array.isArray(answers) || answers.length === 0) { + throw new Error('No answers'); + } + const result = answers.map((i) => i?.data).filter((i) => i); + if (result.length === 0) { throw new Error('No answers'); } - const result = answers[answers.length - 1].data; resourceCache.set(id, result); return result; }, @@ -470,10 +482,13 @@ const DOMAIN_RESOLVERS = { }, }); const answers = JSON.parse(resp.body); - if (answers.length === 0) { + if (!Array.isArray(answers) || answers.length === 0) { + throw new Error('No answers'); + } + const result = answers; + if (result.length === 0) { throw new Error('No answers'); } - const result = answers[answers.length - 1]; resourceCache.set(id, result); return result; }, @@ -493,7 +508,10 @@ const DOMAIN_RESOLVERS = { if (answers.length === 0 || String(answers) === '0') { throw new Error('No answers'); } - const result = answers[answers.length - 1]; + const result = answers; + if (result.length === 0) { + throw new Error('No answers'); + } resourceCache.set(id, result); return result; }, @@ -550,10 +568,16 @@ function ResolveDomainOperator({ provider, type: _type, filter, cache }) { proxies.forEach((p) => { if (!p['_no-resolve']) { if (results[p.server]) { + p._resolved_ips = results[p.server]; + const ip = Array.isArray(results[p.server]) + ? results[p.server][ + Math.floor( + Math.random() * results[p.server].length, + ) + ] + : results[p.server]; if (_type === 'IP4P') { - const { server, port } = parseIP4P( - results[p.server], - ); + const { server, port } = parseIP4P(ip); if (server && port) { p._domain = p.server; p.server = server; @@ -568,7 +592,7 @@ function ResolveDomainOperator({ provider, type: _type, filter, cache }) { } } else { p._domain = p.server; - p.server = results[p.server]; + p.server = ip; p.resolved = true; p[`_${type}`] = p.server; if (!isIP(p._IP)) { diff --git a/scripts/demo.js b/scripts/demo.js index 6357f5d..9adef6b 100644 --- a/scripts/demo.js +++ b/scripts/demo.js @@ -8,11 +8,16 @@ function operator(proxies = [], targetPlatform, context) { // 结构大致参考了 Clash.Meta(mihomo) 有私货 // 可在预览界面点击节点查看 JSON 结构 或查看 `target=JSON` 的通用订阅 // 1. `_no-resolve` 为不解析域名 - // 2. 域名解析后 会多一个 `_resolved` 字段 - // 3. 域名解析后会有`_IPv4`, `_IPv6`, `_IP`(若有多个步骤, 只取第一次成功的 v4 或 v6 数据), `_domain` 字段 + // 2. 域名解析后 会多一个 `_resolved` 字段, 表示是否解析成功 + // 3. 域名解析后会有`_IPv4`, `_IPv6`, `_IP`(若有多个步骤, 只取第一次成功的 v4 或 v6 数据), `_domain` 字段, `_resolved_ips` 为解析出的所有 IP // 4. 节点字段 `exec` 为 `ssr-local` 路径, 默认 `/usr/local/bin/ssr-local`; 端口从 10000 开始递增(暂不支持配置) // 5. `_subName` 为单条订阅名 // 6. `_collectionName` 为组合订阅名 + // 7. `tls-fingerprint` 为 tls 指纹 + // 8. `underlying-proxy` 为前置代理 + // 9. `trojan`, `tuic`, `hysteria`, `hysteria2`, `juicity` 会在解析时设置 `tls`: true (会使用 tls 类协议的通用逻辑), 输出时删除 + // 10. `sni` 在某些协议里会自动与 `servername` 转换 + // 11. 读取节点的 ca-str 和 _ca (后端文件路径) 字段, 自动计算 fingerprint (参考 https://t.me/zhetengsha/1512) // $arguments 为传入的脚本参数