From f75f3c70860b9ca06da291a4f4aea5f9837d6ac7 Mon Sep 17 00:00:00 2001 From: dzhuang Date: Thu, 7 Dec 2023 00:27:00 +0800 Subject: [PATCH 1/7] feat: support hysteria2 for clash.meta --- src/generator/config/subexport.cpp | 24 +++++++++- src/parser/config/proxy.h | 6 +++ src/parser/subparser.cpp | 71 ++++++++++++++++++++++++++++++ src/parser/subparser.h | 3 ++ 4 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/generator/config/subexport.cpp b/src/generator/config/subexport.cpp index 37e71259d..d8f1fed37 100644 --- a/src/generator/config/subexport.cpp +++ b/src/generator/config/subexport.cpp @@ -107,7 +107,7 @@ bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy & std::string target, ret_real_rule; static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.+?)(?:!!(.*))?$)"; static const std::string type_regex = R"(^!!(?:TYPE)=(.+?)(?:!!(.*))?$)", port_regex = R"(^!!(?:PORT)=(.+?)(?:!!(.*))?$)", server_regex = R"(^!!(?:SERVER)=(.+?)(?:!!(.*))?$)"; - static const string_array types = {"", "SS", "SSR", "VMESS", "TROJAN", "SNELL", "HTTP", "HTTPS", "SOCKS5","VLESS","HYSTERIA"}; + static const string_array types = {"", "SS", "SSR", "VMESS", "TROJAN", "SNELL", "HTTP", "HTTPS", "SOCKS5","VLESS","HYSTERIA","HYSTERIA2"}; if (startsWith(rule, "!!GROUP=")) { regGetMatch(rule, group_regex, 3, 0, &target, &ret_real_rule); real_rule = ret_real_rule; @@ -352,6 +352,28 @@ void proxyToClash(std::vector &nodes, YAML::Node &yamlnode, const ProxyGr if (!x.OBFSParam.empty()) singleproxy["obfs"] = x.OBFSParam; break; + case ProxyType::Hysteria2: + singleproxy["type"] = "hysteria2"; + singleproxy["password"] = x.Password; + if (!x.UpMbps.empty()) + singleproxy["up"] = x.UpMbps; + if (!x.DownMbps.empty()) + singleproxy["down"] = x.DownMbps; + if (!tfo.is_undef()) + singleproxy["fast-open"] = tfo.get(); + if (!x.Host.empty()) + singleproxy["sni"] = x.Host; + if (!scv.is_undef()) + singleproxy["skip-cert-verify"] = scv.get(); + if (x.Insecure == "1") + singleproxy["skip-cert-verify"] = true; + if (!x.Alpn.empty()) + singleproxy["alpn"].push_back(x.Alpn); + if (!x.OBFSParam.empty()) + singleproxy["obfs"] = x.OBFSParam; + if (!x.OBFSPassword.empty()) + singleproxy["obfs-password"] = x.OBFSPassword; + break; case ProxyType::VLESS: singleproxy["type"] = "vless"; singleproxy["uuid"] = x.UserId; diff --git a/src/parser/config/proxy.h b/src/parser/config/proxy.h index 02ad6cf35..52265ec36 100644 --- a/src/parser/config/proxy.h +++ b/src/parser/config/proxy.h @@ -15,6 +15,7 @@ enum ProxyType VMess, VLESS, Hysteria, + Hysteria2, Trojan, Snell, HTTP, @@ -36,6 +37,8 @@ inline String getProxyTypeName(int type) return "VLESS"; case ProxyType::Hysteria: return "Hysteria"; + case ProxyType::Hysteria2: + return "Hysteria2"; case ProxyType::Trojan: return "Trojan"; case ProxyType::Snell: @@ -107,6 +110,8 @@ struct Proxy String PublicKey; String ShortId; + String OBFSPassword; + }; #define SS_DEFAULT_GROUP "SSProvider" @@ -114,6 +119,7 @@ struct Proxy #define V2RAY_DEFAULT_GROUP "V2RayProvider" #define XRAY_DEFAULT_GROUP "XRayProvider" #define HYSTERIA_DEFAULT_GROUP "HysteriaProvider" +#define HYSTERIA2_DEFAULT_GROUP "Hysteria2Provider" #define SOCKS_DEFAULT_GROUP "SocksProvider" #define HTTP_DEFAULT_GROUP "HTTPProvider" #define TROJAN_DEFAULT_GROUP "TrojanProvider" diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index 121e1ecbb..b45cbbcf5 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -79,6 +79,19 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string node.FakeType = type; } +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure ,tribool udp, tribool tfo, tribool scv, tribool tls13) +{ + commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tls13); + node.Password = password; + node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host); + node.UpMbps = up; + node.DownMbps = down; + node.Alpn = alpn; + node.OBFSParam = obfsParam; + node.OBFSPassword = obfsPassword; + node.Insecure = insecure; +} + void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,const std::string &pbk, const std::string &sid, const std::string &fp ,tribool udp, tribool tfo, tribool scv, tribool tls13) { commonConstruct(node, ProxyType::VLESS, group, remarks, add, port, udp, tfo, scv, tls13); @@ -188,6 +201,16 @@ void explodeHysteria(std::string hysteria, Proxy &node) } } +void explodeHysteria2(std::string hysteria2, Proxy &node) +{ + printf("explodeHysteria2\n"); + if(regMatch(hysteria2, "hysteria2://(.*?)[:](.*)")) + { + explodeStdHysteria2(hysteria2, node); + return; + } +} + void explodeVmess(std::string vmess, Proxy &node) { std::string version, ps, add, port, type, id, aid, net, path, host, tls, sni, alpn; @@ -1035,6 +1058,7 @@ void explodeClash(Node yamlnode, std::vector &nodes) std::string flow, mode; //trojan std::string user; //socks std::string auth,up,down,obfsParam,insecure;//hysteria + std::string obfsPassword;//hysteria2 tribool udp, tfo, scv; Node singleproxy; uint32_t index = nodes.size(); @@ -1317,6 +1341,19 @@ void explodeClash(Node yamlnode, std::vector &nodes) hysteriaConstruct(node, group, ps, server, port, type, auth, host, up, down, alpn, obfsParam, insecure, udp, tfo, scv); break; + case "hysteria2"_hash: + group = HYSTERIA2_DEFAULT_GROUP; + singleproxy["password"] >> password; + singleproxy["up"] >> up; + singleproxy["down"] >> down; + singleproxy["obfs"] >> obfsParam; + singleproxy["obfs-password"] >> obfsPassword; + singleproxy["sni"] >> host; + singleproxy["alpn"][0] >> alpn; + singleproxy["skip-cert-verify"] >> insecure; + + hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, udp, tfo, scv); + break; default: continue; } @@ -1404,6 +1441,38 @@ void explodeStdHysteria(std::string hysteria, Proxy &node) return; } +void explodeStdHysteria2(std::string hysteria2, Proxy &node) +{ + std::string add, port, password, host, insecure, up, down, alpn, obfsParam, obfsPassword, remarks; + std::string addition; + hysteria2 = hysteria2.substr(12); + string_size pos; + + pos = hysteria2.rfind("#"); + if(pos != hysteria2.npos) + { + remarks = urlDecode(hysteria2.substr(pos + 1)); + hysteria2.erase(pos); + } + const std::string stdhysteria2_matcher = R"(^(.*)[:](\d+)[?](.*)$)"; + if(regGetMatch(hysteria2, stdhysteria2_matcher, 4, 0, &add, &port, &addition)) + return; + password = getUrlArg(addition,"password"); + host = getUrlArg(addition,"peer"); + insecure = getUrlArg(addition, "insecure"); + up = getUrlArg(addition,"upmbps"); + down = getUrlArg(addition,"downmbps"); + alpn = getUrlArg(addition,"alpn"); + obfsParam = getUrlArg(addition,"obfsParam"); + obfsPassword = getUrlArg(addition,"obfsPassword"); + + if(remarks.empty()) + remarks = add + ":" + port; + + hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure); + return; +} + void explodeStdVless(std::string vless, Proxy &node) { std::string add, port, type, id, aid, net, flow, pbk, sid, fp, mode, path, host, tls, remarks; @@ -2335,6 +2404,8 @@ void explode(const std::string &link, Proxy &node) explodeVless(link, node); else if(strFind(link, "hysteria://")) explodeHysteria(link, node); + else if(strFind(link, "hysteria2://")) + explodeHysteria2(link, node); else if(strFind(link, "ss://")) explodeSS(link, node); else if(strFind(link, "socks://") || strFind(link, "https://t.me/socks") || strFind(link, "tg://socks")) diff --git a/src/parser/subparser.h b/src/parser/subparser.h index 56291f13c..685f27225 100644 --- a/src/parser/subparser.h +++ b/src/parser/subparser.h @@ -21,6 +21,7 @@ enum class ConfType }; void hysteriaConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &auth, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &insecure ,tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool()); +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure ,tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool()); void vmessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls, const std::string &sni, const std::string &alpn, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool()); void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,const std::string &pkd, const std::string &sid, const std::string &fp, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool()); void ssrConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &protocol, const std::string &method, const std::string &obfs, const std::string &password, const std::string &obfsparam, const std::string &protoparam, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool()); @@ -32,6 +33,7 @@ void snellConstruct(Proxy &node, const std::string &group, const std::string &re void explodeVmess(std::string vmess, Proxy &node); void explodeVless(std::string vless, Proxy &node); void explodeHysteria(std::string hysteria, Proxy &node); +void explodeHysteria2(std::string hysteria2, Proxy &node); void explodeSSR(std::string ssr, Proxy &node); void explodeSS(std::string ss, Proxy &node); void explodeTrojan(std::string trojan, Proxy &node); @@ -39,6 +41,7 @@ void explodeQuan(const std::string &quan, Proxy &node); void explodeStdVMess(std::string vmess, Proxy &node); void explodeStdVless(std::string vless, Proxy &node); void explodeStdHysteria(std::string hysteria, Proxy &node); +void explodeStdHysteria2(std::string hysteria2, Proxy &node); void explodeShadowrocket(std::string kit, Proxy &node); void explodeKitsunebi(std::string kit, Proxy &node); /// Parse a link From 414eeb6da0de8d7737337c4bea806c6842c06300 Mon Sep 17 00:00:00 2001 From: dzhuang Date: Thu, 7 Dec 2023 11:35:56 +0800 Subject: [PATCH 2/7] Removed fast-open from Hysteria2 and added cwnd. Allow parsing url with password and port. --- src/generator/config/subexport.cpp | 4 +- src/parser/config/proxy.h | 1 + src/parser/subparser.cpp | 70 +++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/generator/config/subexport.cpp b/src/generator/config/subexport.cpp index d8f1fed37..efa01174b 100644 --- a/src/generator/config/subexport.cpp +++ b/src/generator/config/subexport.cpp @@ -359,8 +359,6 @@ void proxyToClash(std::vector &nodes, YAML::Node &yamlnode, const ProxyGr singleproxy["up"] = x.UpMbps; if (!x.DownMbps.empty()) singleproxy["down"] = x.DownMbps; - if (!tfo.is_undef()) - singleproxy["fast-open"] = tfo.get(); if (!x.Host.empty()) singleproxy["sni"] = x.Host; if (!scv.is_undef()) @@ -373,6 +371,8 @@ void proxyToClash(std::vector &nodes, YAML::Node &yamlnode, const ProxyGr singleproxy["obfs"] = x.OBFSParam; if (!x.OBFSPassword.empty()) singleproxy["obfs-password"] = x.OBFSPassword; + if (x.CWND != 0) + singleproxy["cwnd"] = x.CWND; break; case ProxyType::VLESS: singleproxy["type"] = "vless"; diff --git a/src/parser/config/proxy.h b/src/parser/config/proxy.h index 52265ec36..2e047bc08 100644 --- a/src/parser/config/proxy.h +++ b/src/parser/config/proxy.h @@ -111,6 +111,7 @@ struct Proxy String ShortId; String OBFSPassword; + uint16_t CWND; }; diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index b45cbbcf5..306c207fe 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -79,7 +79,7 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string node.FakeType = type; } -void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure ,tribool udp, tribool tfo, tribool scv, tribool tls13) +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure, const std::string &cwnd, tribool udp, tribool tfo, tribool scv, tribool tls13) { commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tls13); node.Password = password; @@ -90,6 +90,7 @@ void hysteria2Construct(Proxy &node, const std::string &group, const std::string node.OBFSParam = obfsParam; node.OBFSPassword = obfsPassword; node.Insecure = insecure; + node.CWND = cwnd; } void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,const std::string &pbk, const std::string &sid, const std::string &fp ,tribool udp, tribool tfo, tribool scv, tribool tls13) @@ -204,7 +205,8 @@ void explodeHysteria(std::string hysteria, Proxy &node) void explodeHysteria2(std::string hysteria2, Proxy &node) { printf("explodeHysteria2\n"); - if(regMatch(hysteria2, "hysteria2://(.*?)[:](.*)")) + hysteria2 = urlSafeBase64Decode(regReplace(hysteria2, "(hysteria2|hy2)://", "hysteria2://")); + if(regMatch(hysteria2, "hysteria2://(.*?)@(.*?)[:](.*)")) { explodeStdHysteria2(hysteria2, node); return; @@ -1350,9 +1352,17 @@ void explodeClash(Node yamlnode, std::vector &nodes) singleproxy["obfs-password"] >> obfsPassword; singleproxy["sni"] >> host; singleproxy["alpn"][0] >> alpn; - singleproxy["skip-cert-verify"] >> insecure; - hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, udp, tfo, scv); + bool skipCertVerify; + singleproxy["skip-cert-verify"] >> skipCertVerify; + if (skipCertVerify) { + insecure = "1"; + } else { + insecure = "0"; + } + singleproxy["cwnd"] >> cwnd; + + hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, cwnd, udp, tfo, scv); break; default: continue; @@ -1454,22 +1464,52 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) remarks = urlDecode(hysteria2.substr(pos + 1)); hysteria2.erase(pos); } - const std::string stdhysteria2_matcher = R"(^(.*)[:](\d+)[?](.*)$)"; - if(regGetMatch(hysteria2, stdhysteria2_matcher, 4, 0, &add, &port, &addition)) - return; - password = getUrlArg(addition,"password"); - host = getUrlArg(addition,"peer"); + + pos = hysteria2.rfind("?"); + if(pos != hysteria2.npos) + { + addition = link.hysteria2(pos + 1); + hysteria2.erase(pos); + } + + if(strFind(hysteria2, "@")) + { + if(regGetMatch(hysteria2, R"(^(.*?)@(.*)[:](\d+)$)", 4, 0, &password, &add, &port)) + return; + } + else + { + password = getUrlArg(addition,"password"); + if(password.empty()) + return; + + if(strFind(hysteria2, ":")) + { + if(regGetMatch(hysteria2, R"(^(.*)[:](\d+)$)", 3, 0, &add, &port)) + return; + } + else + { + port = getUrlArg(addition,"port"); + if(port.empty()) + return; + + add = hysteria2; + } + } + insecure = getUrlArg(addition, "insecure"); - up = getUrlArg(addition,"upmbps"); - down = getUrlArg(addition,"downmbps"); + up = getUrlArg(addition,"up"); + down = getUrlArg(addition,"down"); alpn = getUrlArg(addition,"alpn"); - obfsParam = getUrlArg(addition,"obfsParam"); - obfsPassword = getUrlArg(addition,"obfsPassword"); + obfsParam = getUrlArg(addition,"obfs"); + obfsPassword = getUrlArg(addition,"obfs-password"); + cwnd = getUrlArg(addition,"cwnd"); if(remarks.empty()) remarks = add + ":" + port; - hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure); + hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, cwnd); return; } @@ -2404,7 +2444,7 @@ void explode(const std::string &link, Proxy &node) explodeVless(link, node); else if(strFind(link, "hysteria://")) explodeHysteria(link, node); - else if(strFind(link, "hysteria2://")) + else if(strFind(link, "hysteria2://") || strFind(link, "hy2://")) explodeHysteria2(link, node); else if(strFind(link, "ss://")) explodeSS(link, node); From 44169003a27fdb279f90bec5d2aa1900026fb72c Mon Sep 17 00:00:00 2001 From: dzhuang Date: Thu, 7 Dec 2023 12:28:04 +0800 Subject: [PATCH 3/7] Revert cwnd. --- src/generator/config/subexport.cpp | 2 -- src/parser/config/proxy.h | 1 - src/parser/subparser.cpp | 9 +++------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/generator/config/subexport.cpp b/src/generator/config/subexport.cpp index efa01174b..1a644820c 100644 --- a/src/generator/config/subexport.cpp +++ b/src/generator/config/subexport.cpp @@ -371,8 +371,6 @@ void proxyToClash(std::vector &nodes, YAML::Node &yamlnode, const ProxyGr singleproxy["obfs"] = x.OBFSParam; if (!x.OBFSPassword.empty()) singleproxy["obfs-password"] = x.OBFSPassword; - if (x.CWND != 0) - singleproxy["cwnd"] = x.CWND; break; case ProxyType::VLESS: singleproxy["type"] = "vless"; diff --git a/src/parser/config/proxy.h b/src/parser/config/proxy.h index 2e047bc08..52265ec36 100644 --- a/src/parser/config/proxy.h +++ b/src/parser/config/proxy.h @@ -111,7 +111,6 @@ struct Proxy String ShortId; String OBFSPassword; - uint16_t CWND; }; diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index 306c207fe..4a33749b1 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -79,7 +79,7 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string node.FakeType = type; } -void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure, const std::string &cwnd, tribool udp, tribool tfo, tribool scv, tribool tls13) +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure, tribool udp, tribool tfo, tribool scv, tribool tls13) { commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tls13); node.Password = password; @@ -90,7 +90,6 @@ void hysteria2Construct(Proxy &node, const std::string &group, const std::string node.OBFSParam = obfsParam; node.OBFSPassword = obfsPassword; node.Insecure = insecure; - node.CWND = cwnd; } void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,const std::string &pbk, const std::string &sid, const std::string &fp ,tribool udp, tribool tfo, tribool scv, tribool tls13) @@ -1360,9 +1359,8 @@ void explodeClash(Node yamlnode, std::vector &nodes) } else { insecure = "0"; } - singleproxy["cwnd"] >> cwnd; - hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, cwnd, udp, tfo, scv); + hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, udp, tfo, scv); break; default: continue; @@ -1504,12 +1502,11 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) alpn = getUrlArg(addition,"alpn"); obfsParam = getUrlArg(addition,"obfs"); obfsPassword = getUrlArg(addition,"obfs-password"); - cwnd = getUrlArg(addition,"cwnd"); if(remarks.empty()) remarks = add + ":" + port; - hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, cwnd); + hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure); return; } From facae2c784fc3588bb7a2f5a496c9256c492da4d Mon Sep 17 00:00:00 2001 From: dzhuang Date: Thu, 7 Dec 2023 12:32:34 +0800 Subject: [PATCH 4/7] Fix hysteria2.substr --- src/parser/subparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index 4a33749b1..1e17cbf46 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -1466,7 +1466,7 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) pos = hysteria2.rfind("?"); if(pos != hysteria2.npos) { - addition = link.hysteria2(pos + 1); + addition = hysteria2.substr(pos + 1); hysteria2.erase(pos); } From 93bdc4f39e0116c0a4013234bba432223ad80201 Mon Sep 17 00:00:00 2001 From: dzhuang Date: Thu, 7 Dec 2023 17:57:34 +0800 Subject: [PATCH 5/7] Allow password in addition for Hysteria2. --- src/parser/subparser.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index 1e17cbf46..b80552913 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -203,9 +203,8 @@ void explodeHysteria(std::string hysteria, Proxy &node) void explodeHysteria2(std::string hysteria2, Proxy &node) { - printf("explodeHysteria2\n"); - hysteria2 = urlSafeBase64Decode(regReplace(hysteria2, "(hysteria2|hy2)://", "hysteria2://")); - if(regMatch(hysteria2, "hysteria2://(.*?)@(.*?)[:](.*)")) + hysteria2 = regReplace(hysteria2, "(hysteria2|hy2)://", "hysteria2://"); + if(regMatch(hysteria2, "hysteria2://(.*?)[:](.*)")) { explodeStdHysteria2(hysteria2, node); return; @@ -1354,7 +1353,7 @@ void explodeClash(Node yamlnode, std::vector &nodes) bool skipCertVerify; singleproxy["skip-cert-verify"] >> skipCertVerify; - if (skipCertVerify) { + if (skipCertVerify == true) { insecure = "1"; } else { insecure = "0"; @@ -1479,21 +1478,15 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) { password = getUrlArg(addition,"password"); if(password.empty()) - return; + return; - if(strFind(hysteria2, ":")) - { - if(regGetMatch(hysteria2, R"(^(.*)[:](\d+)$)", 3, 0, &add, &port)) - return; - } - else - { - port = getUrlArg(addition,"port"); - if(port.empty()) + if(!strFind(hysteria2, ":")) return; - add = hysteria2; - } + if(regGetMatch(hysteria2, R"(^(.*)[:](\d+)$)", 3, 0, &add, &port)) + return; + + add = hysteria2; } insecure = getUrlArg(addition, "insecure"); From 8c751ed26112f7dad17b6c92a8ce1e61bcdcd34d Mon Sep 17 00:00:00 2001 From: dzhuang Date: Fri, 8 Dec 2023 09:39:57 +0800 Subject: [PATCH 6/7] Fixed wrong add when password is set in additions part; Added missing sni param. --- src/parser/subparser.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index b80552913..cf6c32bde 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -204,6 +204,9 @@ void explodeHysteria(std::string hysteria, Proxy &node) void explodeHysteria2(std::string hysteria2, Proxy &node) { hysteria2 = regReplace(hysteria2, "(hysteria2|hy2)://", "hysteria2://"); + + // replace /? with ? + hysteria2 = regReplace(hysteria2, "/\\?", "?", true, false); if(regMatch(hysteria2, "hysteria2://(.*?)[:](.*)")) { explodeStdHysteria2(hysteria2, node); @@ -1485,8 +1488,6 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) if(regGetMatch(hysteria2, R"(^(.*)[:](\d+)$)", 3, 0, &add, &port)) return; - - add = hysteria2; } insecure = getUrlArg(addition, "insecure"); @@ -1495,6 +1496,7 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) alpn = getUrlArg(addition,"alpn"); obfsParam = getUrlArg(addition,"obfs"); obfsPassword = getUrlArg(addition,"obfs-password"); + host = getUrlArg(addition,"sni"); if(remarks.empty()) remarks = add + ":" + port; From 45b4e4143600748f2147616be27b9cfd77715f89 Mon Sep 17 00:00:00 2001 From: dzhuang Date: Fri, 8 Dec 2023 21:32:01 +0800 Subject: [PATCH 7/7] Better insecure logic. --- src/generator/config/subexport.cpp | 2 -- src/parser/subparser.cpp | 34 ++++++++++++------------------ 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/generator/config/subexport.cpp b/src/generator/config/subexport.cpp index 1a644820c..d4799a652 100644 --- a/src/generator/config/subexport.cpp +++ b/src/generator/config/subexport.cpp @@ -363,8 +363,6 @@ void proxyToClash(std::vector &nodes, YAML::Node &yamlnode, const ProxyGr singleproxy["sni"] = x.Host; if (!scv.is_undef()) singleproxy["skip-cert-verify"] = scv.get(); - if (x.Insecure == "1") - singleproxy["skip-cert-verify"] = true; if (!x.Alpn.empty()) singleproxy["alpn"].push_back(x.Alpn); if (!x.OBFSParam.empty()) diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index cf6c32bde..6a3bafe19 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -79,9 +79,9 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string node.FakeType = type; } -void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure, tribool udp, tribool tfo, tribool scv, tribool tls13) +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, tribool udp, tribool tfo, tribool scv) { - commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tls13); + commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tribool()); node.Password = password; node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host); node.UpMbps = up; @@ -89,7 +89,6 @@ void hysteria2Construct(Proxy &node, const std::string &group, const std::string node.Alpn = alpn; node.OBFSParam = obfsParam; node.OBFSPassword = obfsPassword; - node.Insecure = insecure; } void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,const std::string &pbk, const std::string &sid, const std::string &fp ,tribool udp, tribool tfo, tribool scv, tribool tls13) @@ -1346,23 +1345,15 @@ void explodeClash(Node yamlnode, std::vector &nodes) break; case "hysteria2"_hash: group = HYSTERIA2_DEFAULT_GROUP; - singleproxy["password"] >> password; - singleproxy["up"] >> up; - singleproxy["down"] >> down; - singleproxy["obfs"] >> obfsParam; - singleproxy["obfs-password"] >> obfsPassword; - singleproxy["sni"] >> host; - singleproxy["alpn"][0] >> alpn; - - bool skipCertVerify; - singleproxy["skip-cert-verify"] >> skipCertVerify; - if (skipCertVerify == true) { - insecure = "1"; - } else { - insecure = "0"; - } + singleproxy["password"] >>= password; + singleproxy["up"] >>= up; + singleproxy["down"] >>= down; + singleproxy["obfs"] >>= obfsParam; + singleproxy["obfs-password"] >>= obfsPassword; + singleproxy["sni"] >>= host; + singleproxy["alpn"][0] >>= alpn; - hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, udp, tfo, scv); + hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam, obfsPassword, udp, tfo, scv); break; default: continue; @@ -1455,6 +1446,7 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) { std::string add, port, password, host, insecure, up, down, alpn, obfsParam, obfsPassword, remarks; std::string addition; + tribool scv; hysteria2 = hysteria2.substr(12); string_size pos; @@ -1490,7 +1482,7 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) return; } - insecure = getUrlArg(addition, "insecure"); + scv = getUrlArg(addition, "insecure"); up = getUrlArg(addition,"up"); down = getUrlArg(addition,"down"); alpn = getUrlArg(addition,"alpn"); @@ -1501,7 +1493,7 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) if(remarks.empty()) remarks = add + ":" + port; - hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure); + hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, password, host, up, down, alpn, obfsParam, obfsPassword, tribool(), tribool(), scv); return; }