From d8908f4dce6867a84d1651eb14ccaacb05814865 Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Sun, 1 Dec 2019 18:13:16 +0800 Subject: [PATCH] Enhancements Fix broken LAN list. Add support for "no-resolve"/"force-remote-dns" in exporting Clash subscriptions. Optimize codes. --- ini_reader.h | 6 ++--- main.cpp | 13 ++++++++-- misc.cpp | 8 +++--- misc.h | 4 +-- nodemanip.cpp | 13 +++++----- rules/LocalAreaNetwork.list | 38 ++++++--------------------- speedtestutil.cpp | 31 ++++++++-------------- speedtestutil.h | 2 +- subexport.cpp | 51 ++++++++++++++++++++++++++++++++----- subexport.h | 1 + webget.cpp | 3 ++- webserver.cpp | 4 ++- webserver_libevent.cpp | 15 ++++++++--- 13 files changed, 108 insertions(+), 81 deletions(-) diff --git a/ini_reader.h b/ini_reader.h index e1145ed..674c57a 100644 --- a/ini_reader.h +++ b/ini_reader.h @@ -138,8 +138,7 @@ public: if(store_isolated_line) curSection = isolated_items_section; //items before any section define will be store in this section strStrm< std::string {return x.first;}); return retData; } @@ -519,8 +519,6 @@ public: */ int Set(std::string section, std::string itemName, std::string itemVal) { - std::string value; - if(!section.size()) return -1; diff --git a/main.cpp b/main.cpp index c6335be..f32be8b 100644 --- a/main.cpp +++ b/main.cpp @@ -36,6 +36,7 @@ std::string proxy_ruleset, proxy_subscription; std::string clash_rule_base; string_array clash_extra_group; std::string surge_rule_base, surfboard_rule_base, mellow_rule_base; +std::string surge_ssr_path; void setcd(char *argv[]) { @@ -59,11 +60,11 @@ void setcd(char *argv[]) chdir(path.data()); } + std::string refreshRulesets() { guarded_mutex guard(on_configuring); eraseElements(ruleset_content_array); - string_array vArray; std::string rule_group, rule_url; ruleset_content rc; @@ -137,7 +138,7 @@ void readConf() if(ini.ItemPrefixExist("exclude_remarks")) ini.GetAll("exclude_remarks", def_exclude_remarks); if(ini.ItemPrefixExist("include_remarks")) - ini.GetAll("include_remarks", def_exclude_remarks); + ini.GetAll("include_remarks", def_include_remarks); if(ini.ItemExist("clash_rule_base")) clash_rule_base = ini.Get("clash_rule_base"); if(ini.ItemExist("surge_rule_base")) @@ -158,6 +159,13 @@ void readConf() safe_set_renames(renames_temp); } + if(ini.SectionExist("surge_external_proxy")) + { + ini.EnterSection("surge_external_proxy"); + if(ini.ItemExist("surge_ssr_path")) + surge_ssr_path = ini.Get("surge_ssr_path"); + } + ini.EnterSection("managed_config"); if(ini.ItemExist("write_managed_config")) write_managed_config = ini.GetBool("write_managed_config"); @@ -249,6 +257,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) ext.tfo = tfo == "true"; ext.udp = udp == "true"; ext.nodelist = nodelist == "true"; + ext.surge_ssr_path = surge_ssr_path; if(!url.size()) url = default_url; diff --git a/misc.cpp b/misc.cpp index 4c47dae..a98ad61 100644 --- a/misc.cpp +++ b/misc.cpp @@ -99,7 +99,7 @@ void StringToWstring(std::wstring& szDst, std::string str) memset(wszUtf8, 0, len * 2 + 2); MultiByteToWideChar(CP_ACP, 0, (LPCSTR)temp.c_str(), -1, (LPWSTR)wszUtf8, len); szDst = wszUtf8; - std::wstring r = wszUtf8; + //std::wstring r = wszUtf8; delete[] wszUtf8; } #endif // _WIN32 @@ -650,7 +650,7 @@ bool is_str_utf8(std::string data) { const char *str = data.c_str(); unsigned int nBytes = 0; - unsigned char chr = *str; + unsigned char chr; bool bAllAscii = true; for (unsigned int i = 0; str[i] != '\0'; ++i) { @@ -728,14 +728,14 @@ void shortDisassemble(int source, unsigned short &num_a, unsigned short &num_b) num_b = (unsigned short)(source >> 16); } -std::string to_string(YAML::Node &node) +std::string to_string(const YAML::Node &node) { std::stringstream ss; ss << node; return ss.str(); } -std::string getFormData(std::string &raw_data) +std::string getFormData(const std::string &raw_data) { std::stringstream strstrm; std::string line; diff --git a/misc.h b/misc.h index 7ac51ed..2cd3186 100644 --- a/misc.h +++ b/misc.h @@ -37,7 +37,7 @@ std::string trim(const std::string& str); std::string getSystemProxy(); std::string rand_str(const int len); bool is_str_utf8(std::string data); -std::string getFormData(std::string &raw_data); +std::string getFormData(const std::string &raw_data); void sleep(int interval); bool regFind(std::string src, std::string target); @@ -51,7 +51,7 @@ void urlParse(std::string url, std::string &host, std::string &path, int &port, void removeUTF8BOM(std::string &data); int shortAssemble(unsigned short num_a, unsigned short num_b); void shortDisassemble(int source, unsigned short &num_a, unsigned short &num_b); -std::string to_string(YAML::Node &node); +std::string to_string(const YAML::Node &node); std::string fileGet(std::string path, bool binary = true); int fileWrite(std::string path, std::string content, bool overwrite); diff --git a/nodemanip.cpp b/nodemanip.cpp index 10a3f19..ea03238 100644 --- a/nodemanip.cpp +++ b/nodemanip.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "nodeinfo.h" #include "printout.h" @@ -13,11 +14,11 @@ int socksport; bool ss_libev, ssr_libev; extern bool api_mode; -void copyNodes(std::vector *source, std::vector *dest) +void copyNodes(std::vector &source, std::vector &dest) { - for(auto &x : *source) + for(auto &x : source) { - dest->push_back(x); + dest.emplace_back(x); } } @@ -26,7 +27,7 @@ void addNodes(std::string link, std::vector &allNodes, int groupID, st int linkType = -1; std::vector nodes; nodeInfo node; - std::string strSub, strInput, fileContent, strProxy; + std::string strSub; link = replace_all_distinct(link, "\"", ""); writeLog(LOG_TYPE_INFO, "Received Link."); @@ -72,7 +73,7 @@ void addNodes(std::string link, std::vector &allNodes, int groupID, st explodeConfContent(strSub, override_conf_port, socksport, ss_libev, ssr_libev, nodes, exclude_remarks, include_remarks); for(nodeInfo &x : nodes) x.groupID = groupID; - copyNodes(&nodes, &allNodes); + copyNodes(nodes, allNodes); } else { @@ -91,7 +92,7 @@ void addNodes(std::string link, std::vector &allNodes, int groupID, st { for(nodeInfo &x : nodes) x.groupID = groupID; - copyNodes(&nodes, &allNodes); + copyNodes(nodes, allNodes); } break; default: diff --git a/rules/LocalAreaNetwork.list b/rules/LocalAreaNetwork.list index f5f7862..0688b1e 100644 --- a/rules/LocalAreaNetwork.list +++ b/rules/LocalAreaNetwork.list @@ -1,32 +1,10 @@ DOMAIN-SUFFIX,local -IP-CIDR,0.0.0.0/8 -IP-CIDR,10.0.0.0/8 -IP-CIDR,100.64.0.0/10 -IP-CIDR,127.0.0.0/8 -IP-CIDR,169.254.0.0/16 -IP-CIDR,172.16.0.0/12 -IP-CIDR,192.0.0.0/24 -IP-CIDR,192.0.2.0/24 -IP-CIDR,192.88.99.0/24 IP-CIDR,192.168.0.0/16 -IP-CIDR,198.18.0.0/15 -IP-CIDR,198.51.100.0/24 -IP-CIDR,203.0.113.0/24 -IP-CIDR,224.0.0.0/4 -IP-CIDR,240.0.0.0/4 -IP-CIDR,255.255.255.255/32 -IP-CIDR6,::/0 -IP-CIDR6,::/128 -IP-CIDR6,::1/128 -IP-CIDR6,::ffff:0:0/96 -IP-CIDR6,::ffff:0:0:0/96 -IP-CIDR6,64:ff9b::/96 -IP-CIDR6,100::/64 -IP-CIDR6,2001::/32 -IP-CIDR6,2001:20::/28 -IP-CIDR6,2001:db8::/32 -IP-CIDR6,2002::/16 -IP-CIDR6,fc00::/7 -IP-CIDR6,fe80::/10 -IP-CIDR6,ff00::/8 -IP-CIDR6,fd00::/8 +IP-CIDR,10.0.0.0/8 +IP-CIDR,172.16.0.0/12 +IP-CIDR,127.0.0.0/8 +IP-CIDR,100.64.0.0/10 +IP-CIDR,::1/128 +IP-CIDR,fc00::/7 +IP-CIDR,fe80::/10 +IP-CIDR,fd00::/8 diff --git a/speedtestutil.cpp b/speedtestutil.cpp index 510ed8f..7bbfb24 100644 --- a/speedtestutil.cpp +++ b/speedtestutil.cpp @@ -815,7 +815,7 @@ void explodeClash(Node yamlnode, std::string custom_port, int local_port, std::v { nodeInfo node; unsigned int index = nodes.size(); - std::string proxytype, strTemp, ps, server, port, cipher, group, password; //common + std::string proxytype, ps, server, port, cipher, group, password; //common std::string type = "none", id, aid = "0", net = "tcp", path, host, tls; //vmess std::string plugin, pluginopts, pluginopts_mode, pluginopts_host; //ss std::string protocol, protoparam, obfs, obfsparam; //ssr @@ -948,7 +948,7 @@ void explodeClash(Node yamlnode, std::string custom_port, int local_port, std::v void explodeShadowrocket(std::string kit, std::string custom_port, int local_port, nodeInfo &node) { - std::string ps, add, port, type, id, aid, net = "tcp", path, host, tls, cipher, remarks; + std::string add, port, type, id, aid, net = "tcp", path, host, tls, cipher, remarks; std::string addition; string_array userinfo; kit = replace_all_distinct(kit, "vmess://", ""); @@ -984,7 +984,7 @@ void explodeShadowrocket(std::string kit, std::string custom_port, int local_por void explodeKitsunebi(std::string kit, std::string custom_port, int local_port, nodeInfo &node) { - std::string ps, add, port, type, id, aid = "0", net = "tcp", path, host, tls, cipher = "auto", remarks; + std::string add, port, type, id, aid = "0", net = "tcp", path, host, tls, cipher = "auto", remarks; std::string addition; string_array userinfo; kit = replace_all_distinct(kit, "vmess1://", ""); @@ -1027,12 +1027,11 @@ void explodeKitsunebi(std::string kit, std::string custom_port, int local_port, bool explodeSurge(std::string surge, std::string custom_port, int local_port, std::vector &nodes, bool libev) { - std::string line, remarks, server, port, method, username, password; //common + std::string remarks, server, port, method, username, password; //common std::string plugin, pluginopts, pluginopts_mode, pluginopts_host = "cloudfront.net", mod_url, mod_md5; //ss std::string id, net, tls, host, path; //v2 std::string protocol, protoparam; //ssr std::string itemName, itemVal; - std::stringstream data; std::vector configs, vArray, headers, header; std::multimap proxies; nodeInfo node; @@ -1358,25 +1357,17 @@ void explodeNetchConf(std::string netch, bool ss_libev, bool ssr_libev, std::str } } -bool chkIgnore(nodeInfo &node, string_array &exclude_remarks, string_array &include_remarks) +bool chkIgnore(const nodeInfo &node, string_array &exclude_remarks, string_array &include_remarks) { bool excluded = false, included = false; //std::string remarks = UTF8ToGBK(node.remarks); std::string remarks = node.remarks; writeLog(LOG_TYPE_INFO, "Comparing exclude remarks..."); - for(auto &x : exclude_remarks) - { - if(regFind(remarks, x)) - excluded = true; - } + excluded = std::any_of(exclude_remarks.cbegin(), exclude_remarks.cend(), [&remarks](auto &x){return regFind(remarks, x);}); if(include_remarks.size() != 0) { writeLog(LOG_TYPE_INFO, "Comparing include remarks..."); - for(auto &x : include_remarks) - { - if(regFind(remarks, x)) - included = true; - } + included = std::any_of(include_remarks.cbegin(), include_remarks.cend(), [&remarks](auto &x){return regFind(remarks, x);}); } else { @@ -1460,8 +1451,8 @@ int explodeConfContent(std::string content, std::string custom_port, int local_p { writeLog(LOG_TYPE_INFO, "Node " + iter->group + " - " + iter->remarks + " has been added."); iter->id = index; - index++; - iter++; + ++index; + ++iter; } } @@ -1550,8 +1541,8 @@ void explodeSub(std::string sub, bool sslibev, bool ssrlibev, std::string custom { writeLog(LOG_TYPE_INFO, "Node " + iter->group + " - " + iter->remarks + " has been added."); iter->id = index; - index++; - iter++; + ++index; + ++iter; } } } diff --git a/speedtestutil.h b/speedtestutil.h index 879cb3e..5ee8449 100644 --- a/speedtestutil.h +++ b/speedtestutil.h @@ -23,6 +23,6 @@ void explodeSSD(std::string link, bool libev, std::string custom_port, int local void explodeSub(std::string sub, bool sslibev, bool ssrlibev, std::string custom_port, int local_port, std::vector &nodes, string_array &exclude_remarks, string_array &include_remarks); int explodeConf(std::string filepath, std::string custom_port, int local_port, bool sslibev, bool ssrlibev, std::vector &nodes, string_array &exclude_remarks, string_array &include_remarks); int explodeConfContent(std::string content, std::string custom_port, int local_port, bool sslibev, bool ssrlibev, std::vector &nodes, string_array &exclude_remarks, string_array &include_remarks); -bool chkIgnore(nodeInfo &node, string_array &exclude_remarks, string_array &include_remarks); +bool chkIgnore(const nodeInfo &node, string_array &exclude_remarks, string_array &include_remarks); #endif // SPEEDTESTUTIL_H_INCLUDED diff --git a/subexport.cpp b/subexport.cpp index 972d600..d8cafec 100644 --- a/subexport.cpp +++ b/subexport.cpp @@ -8,6 +8,7 @@ #include "multithread.h" #include +#include #include #include #include @@ -266,7 +267,7 @@ void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset { try_config_lock(); string_array allRules, vArray; - std::string rule_group, rule_path, retrived_rules, strLine; + std::string rule_group, retrived_rules, strLine; std::stringstream strStrm; YAML::Node Rules; @@ -293,14 +294,17 @@ void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset continue; if(strLine.find("USER-AGENT") == 0 || strLine.find("URL-REGEX") == 0 || strLine.find("PROCESS-NAME") == 0) //remove unsupported types continue; + /* if(strLine.find("IP-CIDR") == 0) strLine = replace_all_distinct(strLine, ",no-resolve", ""); else if(strLine.find("DOMAIN-SUFFIX") == 0) strLine = replace_all_distinct(strLine, ",force-remote-dns", ""); + */ strLine += "," + rule_group; - //if(strLine.find("IP-CIDR") == 0) - //strLine = regReplace(strLine, "^(.*)(,no-resolve)(.*)$", "$1$3$2"); + if(std::count(strLine.begin(), strLine.end(), ',') > 2) + strLine = regReplace(strLine, "^(.*?,.*?)(,.*)(,.*)$", "$1$3$2"); allRules.emplace_back(strLine); + //Rules.push_back(strLine); } } @@ -308,13 +312,14 @@ void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset { Rules.push_back(x); } + base_rule["Rule"] = Rules; } void rulesetToSurge(INIReader &base_rule, std::vector &ruleset_content_array, int surge_ver) { try_config_lock(); - string_array allRules, vArray; + string_array allRules; std::string rule_group, rule_path, retrived_rules, strLine; std::stringstream strStrm; @@ -591,6 +596,7 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s std::string proxy; std::string type, remark, hostname, port, username, password, method; std::string plugin, pluginopts; + std::string protocol, protoparam, obfs, obfsparam; std::string id, aid, transproto, faketype, host, path, quicsecure, quicsecret; std::string url, group; std::string output_nodelist; @@ -661,6 +667,32 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s else if(transproto == "kcp" || transproto == "h2" || transproto == "quic") continue; } + else if(x.linkType == SPEEDTEST_MESSAGE_FOUNDSSR && ext.surge_ssr_path.size()) + { + /* + if(surge_ver < 4) + continue; + protocol = GetMember(json, "Protocol"); + protoparam = GetMember(json, "ProtocolParam"); + obfs = GetMember(json, "OBFS"); + obfsparam = GetMember(json, "OBFSParam"); + proxy = "external,exec=\"" + ext.surge_ssr_path + "\", args=\""; + string_array args = {"-l", "1080", "-s", hostname, "-p", port, "-m", method, "-k", password, "-o", obfs, "-O", protocol}; + if(obfsparam.size()) + { + args.emplace_back("-g"); + args.emplace_back(obfsparam); + } + if(protoparam.size()) + { + args.emplace_back("-G"); + args.emplace_back(protoparam); + } + proxy += std::accumulate(std::next(args.cbegin()), args.cend(), args[0], [](std::string a, std::string b){return std::move(a) + "\",args=\"" + std::move(b);}); + std::string ipaddr = (isIPv4(hostname) || isIPv6(hostname)) ? hostname : hostnameToIPAddr(hostname); + proxy += "\",local-port=1080,addresses=" + ipaddr; + */ + } else if(x.linkType == SPEEDTEST_MESSAGE_FOUNDSOCKS) { proxy = "socks5, " + hostname + ", " + port; @@ -756,9 +788,12 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s if(!filtered_nodelist.size()) filtered_nodelist.emplace_back("DIRECT"); - proxy = vArray[1]; + proxy = vArray[1] + ","; + /* for(std::string &y : filtered_nodelist) proxy += "," + y; + */ + proxy += std::accumulate(std::next(filtered_nodelist.cbegin()), filtered_nodelist.cend(), filtered_nodelist[0], [](std::string a, std::string b){return std::move(a) + "," + std::move(b);}); if(vArray[1] == "url-test" || vArray[1] == "fallback" || vArray[1] == "load-balance") proxy += ",url=" + url; @@ -997,7 +1032,7 @@ std::string netchToQuanX(std::vector &nodes, extra_settings &ext) std::string type; std::string remark, hostname, port, method; std::string password, plugin, pluginopts; - std::string id, aid, transproto, host, path; + std::string id, transproto, host, path; std::string protocol, protoparam, obfs, obfsparam; std::string proxyStr, allLinks; for(nodeInfo &x : nodes) @@ -1074,7 +1109,6 @@ std::string netchToSSD(std::vector &nodes, std::string &group, extra_s std::string remark, hostname, password, method; std::string plugin, pluginopts; std::string protocol, protoparam, obfs, obfsparam; - std::string proxyStr, allLinks; int port, index = 0; if(!group.size()) group = "SSD"; @@ -1317,9 +1351,12 @@ std::string netchToMellow(std::vector &nodes, std::string &base_conf, */ proxy = vArray[0] + ", "; + /* for(std::string &y : filtered_nodelist) proxy += y + ":"; proxy = proxy.substr(0, proxy.size() - 1); + */ + proxy += std::accumulate(std::next(filtered_nodelist.cbegin()), filtered_nodelist.cend(), filtered_nodelist[0], [](std::string a, std::string b){return std::move(a) + ":" + std::move(b);}); proxy += ", latency, interval=300, timeout=6"; //use hard-coded values for now ini.Set("{NONAME}", proxy); //insert order diff --git a/subexport.h b/subexport.h index 03f46a6..0b4242d 100644 --- a/subexport.h +++ b/subexport.h @@ -18,6 +18,7 @@ struct extra_settings bool udp = false; bool tfo = false; bool nodelist = false; + std::string surge_ssr_path; }; diff --git a/webget.cpp b/webget.cpp index cac204c..ebed435 100644 --- a/webget.cpp +++ b/webget.cpp @@ -62,7 +62,8 @@ int curlPost(std::string url, std::string data, std::string proxy, std::string a struct curl_slist *list = NULL; int retVal = 0; - CURLcode res = curl_global_init(CURL_GLOBAL_ALL); + CURLcode res; + curl_global_init(CURL_GLOBAL_ALL); curl_handle = curl_easy_init(); list = curl_slist_append(list, "Content-Type: application/json;charset='utf-8'"); diff --git a/webserver.cpp b/webserver.cpp index 1454fb2..ca3361c 100644 --- a/webserver.cpp +++ b/webserver.cpp @@ -249,7 +249,7 @@ void handle_req(std::string request, int client_sock) goto end; } - for(std::vector::iterator iter = responses.begin(); iter != responses.end(); iter++) + for(std::vector::iterator iter = responses.begin(); iter != responses.end(); ++iter) { if(iter->method.compare(command) == 0 && iter->path == uri) { @@ -306,12 +306,14 @@ void* start_web_server(void *argv) { //log bind error std::cerr<<"socket bind error!"<(argv); std::string listen_address = args->listen_address; int port = args->port, nthreads = args->max_workers; int i, ret;