Просмотр исходного кода

Enhancements

Add SNI host support in Clash configurations.
Add group name/remark support for Telegram-liked HTTP/Socks 5 links.
Optimize codes.
Tindy X 5 лет назад
Родитель
Сommit
5e2fb2c58b
2 измененных файлов с 78 добавлено и 64 удалено
  1. 74 63
      src/speedtestutil.cpp
  2. 4 1
      src/subexport.cpp

+ 74 - 63
src/speedtestutil.cpp

@@ -81,8 +81,9 @@ void explodeVmess(std::string vmess, const std::string &custom_port, int local_p
         GetMember(jsondata, "port", port);
 
     GetMember(jsondata, "host", host);
-    if(version == "1")
+    switch(to_int(version))
     {
+    case 1:
         if(host.size())
         {
             vArray = split(host, ";");
@@ -92,10 +93,10 @@ void explodeVmess(std::string vmess, const std::string &custom_port, int local_p
                 path = vArray[1];
             }
         }
-    }
-    else if(version == "2")
-    {
+        break;
+    case 2:
         path = GetMember(jsondata, "path");
+        break;
     }
 
     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)
 {
-    std::string remarks, server, port, username, password;
+    std::string group, remarks, server, port, username, password;
     if(strFind(link, "socks://")) //v2rayn socks link
     {
         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");
         username = getUrlArg(link, "user");
         password = getUrlArg(link, "pass");
+        remarks = UrlDecode(getUrlArg(link, "remarks"));
+        group = UrlDecode(getUrlArg(link, "group"));
     }
+    if(group.empty())
+        group = SOCKS_DEFAULT_GROUP;
     if(remarks.empty())
         remarks = server + ":" + port;
     if(custom_port.size())
         port = custom_port;
 
     node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS;
-    node.group = SOCKS_DEFAULT_GROUP;
+    node.group = group;
     node.remarks = remarks;
     node.server = server;
     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)
 {
-    std::string remarks, server, port, username, password;
+    std::string group, remarks, server, port, username, password;
     server = getUrlArg(link, "server");
     port = getUrlArg(link, "port");
     username = getUrlArg(link, "user");
     password = getUrlArg(link, "pass");
     remarks = UrlDecode(getUrlArg(link, "remark"));
+    group = UrlDecode(getUrlArg(link, "group"));
 
+    if(group.empty())
+        group = HTTP_DEFAULT_GROUP;
     if(remarks.empty())
         remarks = server + ":" + port;
     if(custom_port.size())
         port = custom_port;
 
     node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
-    node.group = HTTP_DEFAULT_GROUP;
+    node.group = group;
     node.remarks = remarks;
     node.server = server;
     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 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");
     configs = split(strTemp, ",");
 
@@ -701,27 +709,28 @@ void explodeQuan(std::string quan, const std::string &custom_port, int local_por
                 continue;
             itemName = trim(vArray[0]);
             itemVal = trim(vArray[1]);
-            if(itemName == "group")
-                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")
+            switch(hash_(itemName))
             {
-                std::vector<std::string> headers = split(replace_all_distinct(replace_all_distinct(itemVal, "\"", ""), "[Rr][Nn]", "|"), "|");
-                for(unsigned int j = 0; j < headers.size(); j++)
-                {
-                    if(strFind(headers[j], "Host: "))
-                        host = headers[j].substr(6);
-                    else if(strFind(headers[j], "Edge: "))
-                        edge = headers[j].substr(6);
-                }
+                case "group"_hash: group = itemVal; break;
+                case "over-tls"_hash: tls = itemVal == "true" ? "tls" : ""; break;
+                case "tls-host"_hash: host = itemVal; break;
+                case "obfs-path"_hash: path = replace_all_distinct(itemVal, "\"", ""); break;
+                case "obfs-header"_hash:
+                    headers = split(replace_all_distinct(replace_all_distinct(itemVal, "\"", ""), "[Rr][Nn]", "|"), "|");
+                    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())
             path = "/";
@@ -805,7 +814,7 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
 
     node.remarks = remark;
     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)
@@ -862,41 +871,43 @@ void explodeClash(Node yamlnode, const std::string &custom_port, int local_port,
             singleproxy["password"] >> password;
             if(singleproxy["plugin"].IsDefined())
             {
-                if(safe_as<std::string>(singleproxy["plugin"]) == "obfs")
-                {
-                    plugin = "simple-obfs";
-                    if(singleproxy["plugin-opts"].IsDefined())
-                    {
-                        singleproxy["plugin-opts"]["mode"] >> pluginopts_mode;
-                        if(singleproxy["plugin-opts"]["host"].IsDefined())
-                            singleproxy["plugin-opts"]["host"] >> pluginopts_host;
-                        else
-                            pluginopts_host.clear();
-                    }
-                }
-                else if(safe_as<std::string>(singleproxy["plugin"]) == "v2ray-plugin")
+                switch(hash_(safe_as<std::string>(singleproxy["plugin"])))
                 {
-                    plugin = "v2ray-plugin";
-                    if(singleproxy["plugin-opts"].IsDefined())
-                    {
-                        singleproxy["plugin-opts"]["mode"] >> pluginopts_mode;
-                        if(singleproxy["plugin-opts"]["host"].IsDefined())
-                            singleproxy["plugin-opts"]["host"] >> pluginopts_host;
-                        else
-                            pluginopts_host.clear();
-                        if(singleproxy["plugin-opts"]["tls"].IsDefined())
-                            tls = safe_as<bool>(singleproxy["plugin-opts"]["tls"]) ? "tls;" : "";
-                        else
-                            tls.clear();
-                        if(singleproxy["plugin-opts"]["path"].IsDefined())
-                            singleproxy["plugin-opts"]["path"] >> path;
-                        else
-                            path.clear();
-                        if(singleproxy["plugin-opts"]["mux"].IsDefined())
-                            pluginopts_mux = safe_as<bool>(singleproxy["plugin-opts"]["mux"]) ? "mux=4;" : "";
-                        else
-                            pluginopts_mux.clear();
-                    }
+                    case "obfs"_hash:
+                        plugin = "simple-obfs";
+                        if(singleproxy["plugin-opts"].IsDefined())
+                        {
+                            singleproxy["plugin-opts"]["mode"] >> pluginopts_mode;
+                            if(singleproxy["plugin-opts"]["host"].IsDefined())
+                                singleproxy["plugin-opts"]["host"] >> pluginopts_host;
+                            else
+                                pluginopts_host.clear();
+                        }
+                        break;
+                    case "v2ray-plugin"_hash:
+                        plugin = "v2ray-plugin";
+                        if(singleproxy["plugin-opts"].IsDefined())
+                        {
+                            singleproxy["plugin-opts"]["mode"] >> pluginopts_mode;
+                            if(singleproxy["plugin-opts"]["host"].IsDefined())
+                                singleproxy["plugin-opts"]["host"] >> pluginopts_host;
+                            else
+                                pluginopts_host.clear();
+                            if(singleproxy["plugin-opts"]["tls"].IsDefined())
+                                tls = safe_as<bool>(singleproxy["plugin-opts"]["tls"]) ? "tls;" : "";
+                            else
+                                tls.clear();
+                            if(singleproxy["plugin-opts"]["path"].IsDefined())
+                                singleproxy["plugin-opts"]["path"] >> path;
+                            else
+                                path.clear();
+                            if(singleproxy["plugin-opts"]["mux"].IsDefined())
+                                pluginopts_mux = safe_as<bool>(singleproxy["plugin-opts"]["mux"]) ? "mux=4;" : "";
+                            else
+                                pluginopts_mux.clear();
+                        }
+                        break;
+                    default: break;
                 }
             }
             else if(singleproxy["obfs"].IsDefined())

+ 4 - 1
src/subexport.cpp

@@ -47,7 +47,7 @@ std::string hostnameToIPAddr(const std::string &host)
         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)
         {
@@ -907,8 +907,11 @@ void netchToClash(std::vector<nodeInfo> &nodes, YAML::Node &yamlnode, string_arr
                 singleproxy["skip-cert-verify"] = true;
             break;
         case SPEEDTEST_MESSAGE_FOUNDTROJAN:
+            host = GetMember(json, "Host");
             singleproxy["type"] = "trojan";
             singleproxy["password"] = password;
+            if(host.size())
+                singleproxy["sni"] = host;
             if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty())
                 singleproxy["password"].SetTag("str");
             if(ext.skip_cert_verify)