Skip to content

Commit b3bf582

Browse files
committed
feat: Loon 输入输出支持 AnyTLS
1 parent c07a15b commit b3bf582

5 files changed

Lines changed: 91 additions & 6 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.21.35",
3+
"version": "2.21.36",
44
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
55
"main": "src/main.js",
66
"scripts": {

backend/src/core/proxy-utils/parsers/index.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,15 @@ function Loon_Trojan() {
14481448
const parse = (line) => getLoonParser().parse(line);
14491449
return { name, test, parse };
14501450
}
1451+
function Loon_AnyTLS() {
1452+
const name = 'Loon AnyTLS Parser';
1453+
const test = (line) => {
1454+
return /^.*=\s*anytls/i.test(line.split(',')[0]);
1455+
};
1456+
1457+
const parse = (line) => getLoonParser().parse(line);
1458+
return { name, test, parse };
1459+
}
14511460
function Loon_Hysteria2() {
14521461
const name = 'Loon Hysteria2 Parser';
14531462
const test = (line) => {
@@ -1593,8 +1602,8 @@ function Surge_Direct() {
15931602
const parse = (line) => getSurgeParser().parse(line);
15941603
return { name, test, parse };
15951604
}
1596-
function Surge_Anytls() {
1597-
const name = 'Surge Anytls Parser';
1605+
function Surge_AnyTLS() {
1606+
const name = 'Surge AnyTLS Parser';
15981607
const test = (line) => {
15991608
return /^.*=\s*anytls/.test(line.split(',')[0]);
16001609
};
@@ -1802,7 +1811,7 @@ export default [
18021811
URI_AnyTLS(),
18031812
Clash_All(),
18041813
Surge_Direct(),
1805-
Surge_Anytls(),
1814+
Surge_AnyTLS(),
18061815
Surge_TrustTunnel(),
18071816
Surge_SSH(),
18081817
Surge_SS(),
@@ -1821,6 +1830,7 @@ export default [
18211830
Loon_Vless(),
18221831
Loon_Hysteria2(),
18231832
Loon_Trojan(),
1833+
Loon_AnyTLS(),
18241834
Loon_Http(),
18251835
Loon_Socks5(),
18261836
Loon_WireGuard(),

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const grammars = String.raw`
3535
}
3636
}
3737
38-
start = (shadowsocksr/shadowsocks/vmess/vless/trojan/https/http/socks5/hysteria2) {
38+
start = (shadowsocksr/shadowsocks/vmess/vless/trojan/https/http/socks5/hysteria2/anytls) {
3939
return proxy;
4040
}
4141
@@ -68,6 +68,10 @@ trojan = tag equals "trojan"i address password (transport/transport_host/transpo
6868
proxy.type = "trojan";
6969
handleTransport();
7070
}
71+
anytls = tag equals "anytls"i address password (transport/transport_host/transport_path/over_tls/tls_name/sni/tls_verification/tls_cert_sha256/tls_pubkey_sha256/fast_open/udp_relay/ip_mode/block_quic/idle_session_check_interval/idle_session_timeout/min_idle_session/max_stream_count/others)* {
72+
proxy.type = "anytls";
73+
handleTransport();
74+
}
7175
hysteria2 = tag equals "hysteria2"i address password (tls_name/sni/tls_verification/tls_cert_sha256/tls_pubkey_sha256/udp_relay/fast_open/download_bandwidth/salamander_password/ecn/ip_mode/block_quic/others)* {
7276
proxy.type = "hysteria2";
7377
}
@@ -195,6 +199,11 @@ salamander_password = comma "salamander-password" equals match:[^,]+ { proxy['ob
195199
196200
block_quic = comma "block-quic" equals flag:bool { if(flag) proxy["block-quic"] = "on"; else proxy["block-quic"] = "off"; }
197201
202+
idle_session_check_interval = comma "idle-session-check-interval" equals match:$[0-9]+ { proxy["idle-session-check-interval"] = parseInt(match.trim()); }
203+
idle_session_timeout = comma "idle-session-timeout" equals match:$[0-9]+ { proxy["idle-session-timeout"] = parseInt(match.trim()); }
204+
min_idle_session = comma "min-idle-session" equals match:$[0-9]+ { proxy["min-idle-session"] = parseInt(match.trim()); }
205+
max_stream_count = comma "max-stream-count" equals match:$[0-9]+ { proxy["max-stream-count"] = parseInt(match.trim()); }
206+
198207
tag = match:[^=,]* { proxy.name = match.join("").trim(); }
199208
comma = _ "," _
200209
equals = _ "=" _

backend/src/core/proxy-utils/parsers/peggy/loon.peg

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
}
3434
}
3535

36-
start = (shadowsocksr/shadowsocks/vmess/vless/trojan/https/http/socks5/hysteria2) {
36+
start = (shadowsocksr/shadowsocks/vmess/vless/trojan/https/http/socks5/hysteria2/anytls) {
3737
return proxy;
3838
}
3939

@@ -66,6 +66,10 @@ trojan = tag equals "trojan"i address password (transport/transport_host/transpo
6666
proxy.type = "trojan";
6767
handleTransport();
6868
}
69+
anytls = tag equals "anytls"i address password (transport/transport_host/transport_path/over_tls/tls_name/sni/tls_verification/tls_cert_sha256/tls_pubkey_sha256/fast_open/udp_relay/ip_mode/block_quic/idle_session_check_interval/idle_session_timeout/min_idle_session/max_stream_count/others)* {
70+
proxy.type = "anytls";
71+
handleTransport();
72+
}
6973
hysteria2 = tag equals "hysteria2"i address password (tls_name/sni/tls_verification/tls_cert_sha256/tls_pubkey_sha256/udp_relay/fast_open/download_bandwidth/salamander_password/ecn/ip_mode/block_quic/others)* {
7074
proxy.type = "hysteria2";
7175
}
@@ -193,6 +197,11 @@ salamander_password = comma "salamander-password" equals match:[^,]+ { proxy['ob
193197

194198
block_quic = comma "block-quic" equals flag:bool { if(flag) proxy["block-quic"] = "on"; else proxy["block-quic"] = "off"; }
195199

200+
idle_session_check_interval = comma "idle-session-check-interval" equals match:$[0-9]+ { proxy["idle-session-check-interval"] = parseInt(match.trim()); }
201+
idle_session_timeout = comma "idle-session-timeout" equals match:$[0-9]+ { proxy["idle-session-timeout"] = parseInt(match.trim()); }
202+
min_idle_session = comma "min-idle-session" equals match:$[0-9]+ { proxy["min-idle-session"] = parseInt(match.trim()); }
203+
max_stream_count = comma "max-stream-count" equals match:$[0-9]+ { proxy["max-stream-count"] = parseInt(match.trim()); }
204+
196205
tag = match:[^=,]* { proxy.name = match.join("").trim(); }
197206
comma = _ "," _
198207
equals = _ "=" _

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export default function Loon_Producer() {
2828
return shadowsocksr(proxy);
2929
case 'trojan':
3030
return trojan(proxy);
31+
case 'anytls':
32+
return anytls(proxy);
3133
case 'vmess':
3234
return vmess(proxy, opts['include-unsupported-proxy']);
3335
case 'vless':
@@ -306,6 +308,61 @@ function trojan(proxy) {
306308
return result.toString();
307309
}
308310

311+
function anytls(proxy) {
312+
const result = new Result(proxy);
313+
result.append(
314+
`${proxy.name}=anytls,${proxy.server},${proxy.port},"${proxy.password}"`,
315+
);
316+
317+
for (const key of [
318+
'idle-session-check-interval',
319+
'idle-session-timeout',
320+
'min-idle-session',
321+
'max-stream-count',
322+
]) {
323+
// 值为整数 才附加
324+
if (isPresent(proxy, key) && Number.isInteger(proxy[key])) {
325+
result.append(`,${key}=${proxy[key]}`);
326+
}
327+
}
328+
329+
// tls verification
330+
result.appendIfPresent(
331+
`,skip-cert-verify=${proxy['skip-cert-verify']}`,
332+
'skip-cert-verify',
333+
);
334+
335+
// sni
336+
result.appendIfPresent(`,tls-name=${proxy.sni}`, 'sni');
337+
result.appendIfPresent(
338+
`,tls-cert-sha256=${proxy['tls-fingerprint']}`,
339+
'tls-fingerprint',
340+
);
341+
result.appendIfPresent(
342+
`,tls-pubkey-sha256=${proxy['tls-pubkey-sha256']}`,
343+
'tls-pubkey-sha256',
344+
);
345+
346+
// tfo
347+
result.appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo');
348+
349+
// block-quic
350+
if (proxy['block-quic'] === 'on') {
351+
result.append(',block-quic=true');
352+
} else if (proxy['block-quic'] === 'off') {
353+
result.append(',block-quic=false');
354+
}
355+
356+
// udp
357+
if (proxy.udp) {
358+
result.append(`,udp=true`);
359+
}
360+
const ip_version = ipVersions[proxy['ip-version']] || proxy['ip-version'];
361+
result.appendIfPresent(`,ip-mode=${ip_version}`, 'ip-version');
362+
363+
return result.toString();
364+
}
365+
309366
function vmess(proxy) {
310367
const isReality = !!proxy['reality-opts'];
311368

0 commit comments

Comments
 (0)