Enhancements

Add SNI host support in Clash configurations.
Add group name/remark support for Telegram-liked HTTP/Socks 5 links.
Optimize codes.
This commit is contained in:
Tindy X committed 2020-03-31 15:00:56 +08:00
1 parent 775d83af58
commit 5e2fb2c58b
2 files changed
+78 -64

No files matched your search

+74 -63
View File
@@ -81,8 +81,9 @@ void explodeVmess(std::string vmess, const std::string &custom_port, int local_p
GetMember(jsondata, "port", port); GetMember(jsondata, "port", port);
GetMember(jsondata, "host", host); GetMember(jsondata, "host", host);
if(version == "1") switch(to_int(version))
{ {
case 1:
if(host.size()) if(host.size())
{ {
vArray = split(host, ";"); vArray = split(host, ";");
@@ -92,10 +93,10 @@ void explodeVmess(std::string vmess, const std::string &custom_port, int local_p
path = vArray[1]; path = vArray[1];
} }
} }
} break;
else if(version == "2") case 2:
{
path = GetMember(jsondata, "path"); path = GetMember(jsondata, "path");
break;
} }
node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS;
@@ -578,7 +579,7 @@ void explodeSSRConf(std::string content, const std::string &custom_port, int loc
void explodeSocks(std::string link, const std::string &custom_port, nodeInfo &node) void explodeSocks(std::string link, const std::string &custom_port, nodeInfo &node)
{ {
std::string remarks, server, port, username, password; std::string group, remarks, server, port, username, password;
if(strFind(link, "socks://")) //v2rayn socks link if(strFind(link, "socks://")) //v2rayn socks link
{ {
std::vector<std::string> arguments; std::vector<std::string> arguments;
@@ -600,14 +601,18 @@ void explodeSocks(std::string link, const std::string &custom_port, nodeInfo &no
port = getUrlArg(link, "port"); port = getUrlArg(link, "port");
username = getUrlArg(link, "user"); username = getUrlArg(link, "user");
password = getUrlArg(link, "pass"); password = getUrlArg(link, "pass");
remarks = UrlDecode(getUrlArg(link, "remarks"));
group = UrlDecode(getUrlArg(link, "group"));
} }
if(group.empty())
group = SOCKS_DEFAULT_GROUP;
if(remarks.empty()) if(remarks.empty())
remarks = server + ":" + port; remarks = server + ":" + port;
if(custom_port.size()) if(custom_port.size())
port = custom_port; port = custom_port;
node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
node.group = SOCKS_DEFAULT_GROUP; node.group = group;
node.remarks = remarks; node.remarks = remarks;
node.server = server; node.server = server;
node.port = to_int(port, 0); node.port = to_int(port, 0);
@@ -616,20 +621,23 @@ void explodeSocks(std::string link, const std::string &custom_port, nodeInfo &no
void explodeHTTP(std::string link, const std::string &custom_port, nodeInfo &node) void explodeHTTP(std::string link, const std::string &custom_port, nodeInfo &node)
{ {
std::string remarks, server, port, username, password; std::string group, remarks, server, port, username, password;
server = getUrlArg(link, "server"); server = getUrlArg(link, "server");
port = getUrlArg(link, "port"); port = getUrlArg(link, "port");
username = getUrlArg(link, "user"); username = getUrlArg(link, "user");
password = getUrlArg(link, "pass"); password = getUrlArg(link, "pass");
remarks = UrlDecode(getUrlArg(link, "remark")); remarks = UrlDecode(getUrlArg(link, "remark"));
group = UrlDecode(getUrlArg(link, "group"));
if(group.empty())
group = HTTP_DEFAULT_GROUP;
if(remarks.empty()) if(remarks.empty())
remarks = server + ":" + port; remarks = server + ":" + port;
if(custom_port.size()) if(custom_port.size())
port = custom_port; port = custom_port;
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP; node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
node.group = HTTP_DEFAULT_GROUP; node.group = group;
node.remarks = remarks; node.remarks = remarks;
node.server = server; node.server = server;
node.port = to_int(port, 0); node.port = to_int(port, 0);
@@ -679,7 +687,7 @@ void explodeQuan(std::string quan, const std::string &custom_port, int local_por
{ {
std::string strTemp, itemName, itemVal; std::string strTemp, itemName, itemVal;
std::string group = V2RAY_DEFAULT_GROUP, ps, add, port, cipher = "auto", type = "none", id, aid = "0", net = "tcp", path, host, edge, tls; std::string group = V2RAY_DEFAULT_GROUP, ps, add, port, cipher = "auto", type = "none", id, aid = "0", net = "tcp", path, host, edge, tls;
std::vector<std::string> configs, vArray; string_array configs, vArray, headers;
strTemp = regReplace(quan, "(.*?) = (.*)", "$1,$2"); strTemp = regReplace(quan, "(.*?) = (.*)", "$1,$2");
configs = split(strTemp, ","); configs = split(strTemp, ",");
@@ -701,27 +709,28 @@ void explodeQuan(std::string quan, const std::string &custom_port, int local_por
continue; continue;
itemName = trim(vArray[0]); itemName = trim(vArray[0]);
itemVal = trim(vArray[1]); itemVal = trim(vArray[1]);
if(itemName == "group") switch(hash_(itemName))
group = itemVal;
else if(itemName == "over-tls")
tls = itemVal == "true" ? "tls" : "";
else if(itemName == "tls-host")
host = itemVal;
else if(itemName == "obfs-path")
path = replace_all_distinct(itemVal, "\"", "");
else if(itemName == "obfs-header")
{ {
std::vector<std::string> headers = split(replace_all_distinct(replace_all_distinct(itemVal, "\"", ""), "[Rr][Nn]", "|"), "|"); case "group"_hash: group = itemVal; break;
for(unsigned int j = 0; j < headers.size(); j++) case "over-tls"_hash: tls = itemVal == "true" ? "tls" : ""; break;
{ case "tls-host"_hash: host = itemVal; break;
if(strFind(headers[j], "Host: ")) case "obfs-path"_hash: path = replace_all_distinct(itemVal, "\"", ""); break;
host = headers[j].substr(6); case "obfs-header"_hash:
else if(strFind(headers[j], "Edge: ")) headers = split(replace_all_distinct(replace_all_distinct(itemVal, "\"", ""), "[Rr][Nn]", "|"), "|");
edge = headers[j].substr(6); for(std::string &x : headers)
} {
if(regFind(x, "(?i)Host: "))
host = x.substr(6);
else if(regFind(x, "(?i)Edge: "))
edge = x.substr(6);
}
break;
case "obfs"_hash:
if(itemVal == "ws")
net = "ws";
break;
default: continue;
} }
else if(itemName == "obfs" && itemVal == "ws")
net = "ws";
} }
if(path.empty()) if(path.empty())
path = "/"; path = "/";
@@ -805,7 +814,7 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
node.remarks = remark; node.remarks = remark;
node.server = address; node.server = address;
node.port = (unsigned short)to_int(port, 0);; node.port = (unsigned short)to_int(port, 0);
} }
void explodeClash(Node yamlnode, const std::string &custom_port, int local_port, std::vector<nodeInfo> &nodes, bool ss_libev, bool ssr_libev) void explodeClash(Node yamlnode, const std::string &custom_port, int local_port, std::vector<nodeInfo> &nodes, bool ss_libev, bool ssr_libev)
@@ -862,41 +871,43 @@ void explodeClash(Node yamlnode, const std::string &custom_port, int local_port,
singleproxy["password"] >> password; singleproxy["password"] >> password;
if(singleproxy["plugin"].IsDefined()) if(singleproxy["plugin"].IsDefined())
{ {
if(safe_as<std::string>(singleproxy["plugin"]) == "obfs") switch(hash_(safe_as<std::string>(singleproxy["plugin"])))
{ {
plugin = "simple-obfs"; case "obfs"_hash:
if(singleproxy["plugin-opts"].IsDefined()) plugin = "simple-obfs";
{ if(singleproxy["plugin-opts"].IsDefined())
singleproxy["plugin-opts"]["mode"] >> pluginopts_mode; {
if(singleproxy["plugin-opts"]["host"].IsDefined()) singleproxy["plugin-opts"]["mode"] >> pluginopts_mode;
singleproxy["plugin-opts"]["host"] >> pluginopts_host; if(singleproxy["plugin-opts"]["host"].IsDefined())
else singleproxy["plugin-opts"]["host"] >> pluginopts_host;
pluginopts_host.clear(); else
} pluginopts_host.clear();
} }
else if(safe_as<std::string>(singleproxy["plugin"]) == "v2ray-plugin") break;
{ case "v2ray-plugin"_hash:
plugin = "v2ray-plugin"; plugin = "v2ray-plugin";
if(singleproxy["plugin-opts"].IsDefined()) if(singleproxy["plugin-opts"].IsDefined())
{ {
singleproxy["plugin-opts"]["mode"] >> pluginopts_mode; singleproxy["plugin-opts"]["mode"] >> pluginopts_mode;
if(singleproxy["plugin-opts"]["host"].IsDefined()) if(singleproxy["plugin-opts"]["host"].IsDefined())
singleproxy["plugin-opts"]["host"] >> pluginopts_host; singleproxy["plugin-opts"]["host"] >> pluginopts_host;
else else
pluginopts_host.clear(); pluginopts_host.clear();
if(singleproxy["plugin-opts"]["tls"].IsDefined()) if(singleproxy["plugin-opts"]["tls"].IsDefined())
tls = safe_as<bool>(singleproxy["plugin-opts"]["tls"]) ? "tls;" : ""; tls = safe_as<bool>(singleproxy["plugin-opts"]["tls"]) ? "tls;" : "";
else else
tls.clear(); tls.clear();
if(singleproxy["plugin-opts"]["path"].IsDefined()) if(singleproxy["plugin-opts"]["path"].IsDefined())
singleproxy["plugin-opts"]["path"] >> path; singleproxy["plugin-opts"]["path"] >> path;
else else
path.clear(); path.clear();
if(singleproxy["plugin-opts"]["mux"].IsDefined()) if(singleproxy["plugin-opts"]["mux"].IsDefined())
pluginopts_mux = safe_as<bool>(singleproxy["plugin-opts"]["mux"]) ? "mux=4;" : ""; pluginopts_mux = safe_as<bool>(singleproxy["plugin-opts"]["mux"]) ? "mux=4;" : "";
else else
pluginopts_mux.clear(); pluginopts_mux.clear();
} }
break;
default: break;
} }
} }
else if(singleproxy["obfs"].IsDefined()) else if(singleproxy["obfs"].IsDefined())
+4 -1
View File
@@ -47,7 +47,7 @@ std::string hostnameToIPAddr(const std::string &host)
return std::string(); return std::string();
} }
for(cur = retAddrInfo; cur != NULL; cur=cur->ai_next) for(cur = retAddrInfo; cur != NULL; cur = cur->ai_next)
{ {
if(cur->ai_family == AF_INET) if(cur->ai_family == AF_INET)
{ {
@@ -907,8 +907,11 @@ void netchToClash(std::vector<nodeInfo> &nodes, YAML::Node &yamlnode, string_arr
singleproxy["skip-cert-verify"] = true; singleproxy["skip-cert-verify"] = true;
break; break;
case SPEEDTEST_MESSAGE_FOUNDTROJAN: case SPEEDTEST_MESSAGE_FOUNDTROJAN:
host = GetMember(json, "Host");
singleproxy["type"] = "trojan"; singleproxy["type"] = "trojan";
singleproxy["password"] = password; singleproxy["password"] = password;
if(host.size())
singleproxy["sni"] = host;
if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty()) if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty())
singleproxy["password"].SetTag("str"); singleproxy["password"].SetTag("str");
if(ext.skip_cert_verify) if(ext.skip_cert_verify)