Skip to content

Commit 536bb1c

Browse files
committed
feat: Surge TrustTunnel 支持 h3
1 parent 744941c commit 536bb1c

5 files changed

Lines changed: 36 additions & 2 deletions

File tree

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sub-store",
3-
"version": "2.36.33",
3+
"version": "2.36.34",
44
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
55
"main": "src/main.js",
66
"packageManager": "pnpm@11.0.9",

backend/src/core/proxy-utils/parsers/peggy/surge.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ anytls = tag equals "anytls" address (passwordk/reuse/ip_version/underlying_prox
459459
proxy.type = "anytls";
460460
proxy.tls = true;
461461
}
462-
trust_tunnel = tag equals "trust-tunnel" address (usernamek/passwordk/headers/max_streams/reuse/ip_version/underlying_proxy/tos/allow_other_interface/interface/test_url/test_udp/test_timeout/hybrid/no_error_alert/tls_fingerprint/tls_verification/client_cert/sni/cert_verify_name/alpn/fast_open/tfo/block_quic/others)* {
462+
trust_tunnel = tag equals "trust-tunnel" address (usernamek/passwordk/headers/max_streams/reuse/ip_version/underlying_proxy/tos/allow_other_interface/interface/test_url/test_udp/test_timeout/hybrid/no_error_alert/tls_fingerprint/tls_verification/client_cert/sni/cert_verify_name/alpn/h3/fast_open/tfo/block_quic/others)* {
463463
proxy.type = "trusttunnel";
464464
proxy.tls = true;
465465
}
@@ -619,6 +619,7 @@ alpn = comma "alpn" equals match:quoted_value {
619619
const values = parseAlpn(match);
620620
if (values.length > 0) proxy.alpn = values;
621621
}
622+
h3 = comma "h3" equals flag:bool { if (flag) proxy.network = "h3"; }
622623
quoted_value = '"' match:$[^"]* '"' { return match; } / "'" match:$[^']* "'" { return match; } / match:$[^,]+ { return match; }
623624
uuidk = comma "uuid" equals match:[^,]+ { proxy.uuid = match.join(""); }
624625
salamander_password = comma "salamander-password" equals match:[^,]+ { proxy['obfs-password'] = match.join("").replace(/^"(.*?)"$/, '$1').replace(/^'(.*?)'$/, '$1'); proxy.obfs = 'salamander'; }

backend/src/core/proxy-utils/producers/surge.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ function trusttunnel(proxy) {
462462
`,max-streams=${proxy['max-streams']}`,
463463
'max-streams',
464464
);
465+
if (proxy.network === 'h3') result.append(',h3=true');
465466

466467
const ip_version = ipVersions[proxy['ip-version']] || proxy['ip-version'];
467468
result.appendIfPresent(`,ip-version=${ip_version}`, 'ip-version');

backend/src/test/proxy-producers/text.spec.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,37 @@ describe('Proxy text producers', function () {
998998
});
999999
});
10001000

1001+
it('round-trips Surge TrustTunnel h3 as network', function () {
1002+
const [proxy] = ProxyUtils.parse(
1003+
'Surge TrustTunnel H3 = trust-tunnel,trust.example.com,443,h3=true',
1004+
);
1005+
1006+
expect(proxy.network).to.equal('h3');
1007+
expect(proxy).to.not.have.property('alpn');
1008+
1009+
const output = produceExternal('Surge', proxy);
1010+
expect(output).to.include(',h3=true');
1011+
expect(output).to.not.include(',alpn=');
1012+
1013+
const [disabled] = ProxyUtils.parse(
1014+
'Surge TrustTunnel H3 Disabled = trust-tunnel,trust.example.com,443,h3=false',
1015+
);
1016+
expect(disabled).to.not.have.property('network');
1017+
const disabledOutput = produceExternal('Surge', disabled);
1018+
expect(disabledOutput).to.not.include(',h3=true');
1019+
expect(disabledOutput).to.not.include(',alpn=');
1020+
1021+
const alpnOutput = produceExternal('Surge', {
1022+
type: 'trusttunnel',
1023+
name: 'Surge TrustTunnel ALPN H3',
1024+
server: 'trust.example.com',
1025+
port: 443,
1026+
alpn: ['h3'],
1027+
});
1028+
expect(alpnOutput).to.include(',alpn="h3"');
1029+
expect(alpnOutput).to.not.include(',h3=true');
1030+
});
1031+
10011032
it('omits Surge alpn and server-cert-verify-name for non-TLS outputs', function () {
10021033
const output = produceExternal('Surge', [
10031034
{

scripts/demo.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ function operator(proxies = [], targetPlatform, context) {
5959
// 34. VLESS/Trojan URI 的 `vcn` 对应 mihomo 的 `name-cert-verify`. Xray-core 支持用逗号分隔多个 name, mihomo 只支持一个, 因此输入时取第一个有效值, 同时用 `_vcn` 数组保留全部有效值; 输出 URI 时优先用 `_vcn` 还原为 `vcn`, 没有 `_vcn` 时才使用 `name-cert-verify`. 若想设置为其他值, 可使用脚本操作设置, 例如 `$server["name-cert-verify"] = $server._vcn?.[1] || $server._vcn?.[0]`
6060
// 35. sing-box AnyTLS 支持通过节点的字符串字段 `client-metadata` 设置 `client_metadata`
6161
// 36. sing-box Hysteria 2 支持通过节点的字符串字段 `disable-chrome-parrot` 设置 `disable_chrome_parrot`
62+
// 37. Surge TrustTunnel 支持使用 Surge 格式写 `h3=true` 作为输入, 或使用节点字段 `network: 'h3'` 设置 `h3=true`
6263

6364
// require 为 Node.js 的 require, 在 Node.js 运行环境下 可以用来引入模块
6465
// 例如在 Node.js 环境下, 将文件内容写入 /tmp/1.txt 文件

0 commit comments

Comments
 (0)