From 16b7b74260c13ec1925a9edea89ba499e19261bc Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Sun, 24 Nov 2019 00:44:38 +0800 Subject: [PATCH] Bug fixes Fix a potential problem with multi-thread server. Fix support for generating Mellow configuration. --- main.cpp | 20 +++++++++++++------- multithread.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ multithread.h | 17 +++++++++++++++++ subexport.cpp | 36 ++++++++++++++++++++++++------------ 4 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 multithread.cpp create mode 100644 multithread.h diff --git a/main.cpp b/main.cpp index def2632..c7584eb 100644 --- a/main.cpp +++ b/main.cpp @@ -14,6 +14,7 @@ #include "webget.h" #include "webserver.h" #include "subexport.h" +#include "multithread.h" //common settings string_array def_exclude_remarks, def_include_remarks, rulesets; @@ -24,9 +25,8 @@ bool api_mode = true, write_managed_config = false, update_ruleset_on_request = bool print_debug_info = false; extern std::string custom_group; -//safety lock for multi-thread -typedef std::lock_guard guarded_mutex; -std::mutex on_configuring; +//multi-thread lock +extern std::mutex on_configuring; //preferences string_array renames, emojis; @@ -124,8 +124,7 @@ void readConf() eraseElements(def_include_remarks); eraseElements(clash_extra_group); eraseElements(rulesets); - eraseElements(renames); - eraseElements(emojis); + string_array emojis_temp, renames_temp; INIReader ini; //ini.do_utf8_to_gbk = true; ini.ParseFile("pref.ini"); @@ -154,7 +153,10 @@ void readConf() if(ini.ItemExist("proxy_subscription")) proxy_subscription = ini.Get("proxy_subscription"); if(ini.ItemPrefixExist("rename_node")) - ini.GetAll("rename_node", renames); + { + ini.GetAll("rename_node", renames_temp); + safe_set_renames(renames_temp); + } ini.EnterSection("managed_config"); if(ini.ItemExist("write_managed_config")) @@ -168,7 +170,10 @@ void readConf() if(ini.ItemExist("remove_old_emoji")) remove_old_emoji = ini.GetBool("remove_old_emoji"); if(ini.ItemPrefixExist("rule")) - ini.GetAll("rule", emojis); + { + ini.GetAll("rule", emojis_temp); + safe_set_emojis(emojis_temp); + } ini.EnterSection("ruleset"); if(ini.GetBool("enabled")) @@ -257,6 +262,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) custom_group = group; for(std::string &x : urls) { + x = trim(x); std::cerr<<"Fetching node data from url '"< + +#include "misc.h" + +//safety lock for multi-thread +typedef std::lock_guard guarded_mutex; +std::mutex on_configuring, on_emoji, on_rename; + +extern string_array emojis, renames; + +void try_config_lock() +{ + guarded_mutex guard(on_configuring); +} + +void try_emoji_lock() +{ + guarded_mutex guard(on_emoji); +} + +void try_rename_lock() +{ + guarded_mutex guard(on_rename); +} + +string_array safe_get_emojis() +{ + guarded_mutex guard(on_emoji); + return emojis; +} + +string_array safe_get_renames() +{ + guarded_mutex guard(on_rename); + return renames; +} + +void safe_set_emojis(string_array &data) +{ + guarded_mutex guard(on_emoji); + emojis.swap(data); +} + +void safe_set_renames(string_array &data) +{ + guarded_mutex guard(on_rename); + renames.swap(data); +} diff --git a/multithread.h b/multithread.h new file mode 100644 index 0000000..71d033b --- /dev/null +++ b/multithread.h @@ -0,0 +1,17 @@ +#ifndef MULTITHREAD_H_INCLUDED +#define MULTITHREAD_H_INCLUDED + +#include +#include "misc.h" + +typedef std::lock_guard guarded_mutex; + +void try_config_lock(); +void try_emoji_lock(); +void try_rename_lock(); +string_array safe_get_emojis(); +string_array safe_get_renames(); +void safe_set_emojis(string_array &data); +void safe_set_renames(string_array &data); + +#endif // MULTITHREAD_H_INCLUDED diff --git a/subexport.cpp b/subexport.cpp index 6b03c18..0ecafb6 100644 --- a/subexport.cpp +++ b/subexport.cpp @@ -5,6 +5,7 @@ #include "webget.h" #include "subexport.h" #include "printout.h" +#include "multithread.h" #include #include @@ -19,7 +20,9 @@ extern string_array ss_ciphers, ssr_ciphers; std::string vmessConstruct(std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string tls, int local_port) { - if(path == "") + if(!port.size()) + port = "0"; + if(!path.size()) path = "/"; rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); @@ -67,6 +70,8 @@ std::string vmessConstruct(std::string add, std::string port, std::string type, std::string ssrConstruct(std::string group, std::string remarks, std::string remarks_base64, std::string server, std::string port, std::string protocol, std::string method, std::string obfs, std::string password, std::string obfsparam, std::string protoparam, int local_port, bool libev) { + if(!port.size()) + port = "0"; rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); writer.StartObject(); @@ -96,6 +101,8 @@ std::string ssrConstruct(std::string group, std::string remarks, std::string rem std::string ssConstruct(std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, std::string remarks, int local_port, bool libev) { + if(!port.size()) + port = "0"; rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); writer.StartObject(); @@ -121,6 +128,8 @@ std::string ssConstruct(std::string server, std::string port, std::string passwo std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password) { + if(!port.size()) + port = "0"; rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); writer.StartObject(); @@ -142,6 +151,8 @@ std::string socksConstruct(std::string remarks, std::string server, std::string std::string vmessLinkConstruct(std::string remarks, std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string path, std::string host, std::string tls) { + if(!port.size()) + port = "0"; rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); writer.StartObject(); @@ -173,9 +184,9 @@ std::string vmessLinkConstruct(std::string remarks, std::string add, std::string std::string nodeRename(std::string remark) { - string_array vArray; + string_array vArray, renames_temp = safe_get_renames(); - for(std::string &x : renames) + for(std::string &x : renames_temp) { vArray = split(x, "@"); if(vArray.size() == 1) @@ -211,8 +222,8 @@ std::string addEmoji(std::string remark) { if(!add_emoji) return remark; - string_array vArray; - for(std::string &x : emojis) + string_array vArray, emojis_temp = safe_get_emojis(); + for(std::string &x : emojis_temp) { vArray = split(x, ","); if(vArray.size() != 2) @@ -228,6 +239,7 @@ std::string addEmoji(std::string remark) void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset_content_array) { + try_config_lock(); string_array allRules, vArray; std::string rule_group, rule_path, retrived_rules, strLine; std::stringstream strStrm; @@ -276,6 +288,7 @@ void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset void rulesetToSurge(INIReader &base_rule, std::vector &ruleset_content_array, int surge_ver) { + try_config_lock(); string_array allRules, vArray; std::string rule_group, rule_path, retrived_rules, strLine; std::stringstream strStrm; @@ -336,6 +349,7 @@ void rulesetToSurge(INIReader &base_rule, std::vector &ruleset_ std::string netchToClash(std::vector &nodes, std::string &base_conf, std::vector &ruleset_content_array, string_array &extra_proxy_group, bool clashR, extra_settings &ext) { + try_config_lock(); YAML::Node yamlnode, proxies, singleproxy, singlegroup, original_groups; rapidjson::Document json; std::string type, remark, hostname, port, username, password, method; @@ -543,6 +557,7 @@ std::string netchToClash(std::vector &nodes, std::string &base_conf, s std::string netchToSurge(std::vector &nodes, std::string &base_conf, std::vector &ruleset_content_array, string_array &extra_proxy_group, int surge_ver, extra_settings &ext) { + try_config_lock(); rapidjson::Document json; INIReader ini; std::string proxy; @@ -1109,6 +1124,7 @@ std::string netchToSSD(std::vector &nodes, std::string &group, extra_s std::string netchToMellow(std::vector &nodes, std::string &base_conf, std::vector &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext) { + try_config_lock(); rapidjson::Document json; INIReader ini; std::string proxy; @@ -1215,11 +1231,7 @@ std::string netchToMellow(std::vector &nodes, std::string &base_conf, for(unsigned int i = 2; i < rules_upper_bound; i++) { - if(vArray[i].find("[]") == 0) - { - filtered_nodelist.emplace_back(vArray[i].substr(2)); - } - else if(vArray[i].find("!!GROUP=") == 0) + if(vArray[i].find("!!GROUP=") == 0) { group = vArray[i].substr(8); for(nodeInfo &y : nodelist) @@ -1248,7 +1260,7 @@ std::string netchToMellow(std::vector &nodes, std::string &base_conf, } if(!filtered_nodelist.size()) - filtered_nodelist.emplace_back("DIRECT"); + filtered_nodelist = remarks_list; //don't process these for now /* @@ -1261,7 +1273,7 @@ std::string netchToMellow(std::vector &nodes, std::string &base_conf, proxy = vArray[0] + ", "; for(std::string &y : filtered_nodelist) - proxy += "\"" + y + "\":"; + proxy += y + ":"; proxy = proxy.substr(0, proxy.size() - 1); proxy += ", latency, interval=300, timeout=6"; //use hard-coded values for now