diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/.DS_Store b/base/rules/lhie1/Surge/Surge 3/Provider/Media/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/base/rules/lhie1/Surge/Surge 3/Provider/Media/.DS_Store and /dev/null differ diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/AbemaTV.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/AbemaTV.list deleted file mode 100644 index 6ed8079..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/AbemaTV.list +++ /dev/null @@ -1,7 +0,0 @@ -# > AbemaTV -USER-AGENT,AbemaTV* -DOMAIN-SUFFIX,abema.io -DOMAIN-SUFFIX,abema.tv -DOMAIN-SUFFIX,akamaized.net -DOMAIN-SUFFIX,ameba.jp -DOMAIN-SUFFIX,hayabusa.io \ No newline at end of file diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/AppleNews.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/AppleNews.list deleted file mode 100644 index cd2b9a0..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/AppleNews.list +++ /dev/null @@ -1,12 +0,0 @@ -# > Apple News and Apple Map TOMTOM Version -DOMAIN,gspe1-ssl.ls.apple.com -PROCESS-NAME,News -USER-AGENT,AppleNews* -USER-AGENT,com.apple.news* -#USER-AGENT,News* -#DOMAIN,gateway.icloud.com -#DOMAIN,news-events.apple.com -#DOMAIN,apple.comscoreresearch.com -#DOMAIN-SUFFIX,apple.news -#DOMAIN,news-client.apple.com -#DOMAIN,news-edge.apple.com \ No newline at end of file diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/BBC_iPlayer.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/BBC_iPlayer.list deleted file mode 100644 index 99066dd..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/BBC_iPlayer.list +++ /dev/null @@ -1,6 +0,0 @@ -# > BBC iPlayer -USER-AGENT,BBCiPlayer* -DOMAIN-SUFFIX,bbc.co.uk -DOMAIN-SUFFIX,bbci.co.uk -DOMAIN-KEYWORD,bbcfmt -DOMAIN-KEYWORD,uk-live \ No newline at end of file diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/Fox_Now.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/Fox_Now.list deleted file mode 100644 index b18e029..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/Fox_Now.list +++ /dev/null @@ -1,5 +0,0 @@ -# > Fox Now -USER-AGENT,FOX%20NOW* -DOMAIN-SUFFIX,fox.com -DOMAIN-SUFFIX,foxdcg.com -DOMAIN-SUFFIX,uplynk.com \ No newline at end of file diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/Hulu_Japan.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/Hulu_Japan.list deleted file mode 100644 index 1bab2be..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/Hulu_Japan.list +++ /dev/null @@ -1,3 +0,0 @@ -# > Hulu(フールー) -DOMAIN-SUFFIX,happyon.jp -DOMAIN-SUFFIX,hulu.jp \ No newline at end of file diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/Line_TV.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/Line_TV.list deleted file mode 100644 index b9323ae..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/Line_TV.list +++ /dev/null @@ -1,4 +0,0 @@ -# > Line TV -USER-AGENT,LINE* -DOMAIN-SUFFIX,d3c7rimkq79yfu.cloudfront.net -DOMAIN-SUFFIX,linetv.tw \ No newline at end of file diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/Netease_Music.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/Netease_Music.list deleted file mode 100644 index ebdd73c..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/Netease_Music.list +++ /dev/null @@ -1,5 +0,0 @@ -# > NeteaseMusic -USER-AGENT,%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90 -USER-AGENT,NeteaseMusic* -DOMAIN-SUFFIX,music.126.net -DOMAIN-SUFFIX,music.163.com \ No newline at end of file diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/YouTube_Music.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/YouTube_Music.list deleted file mode 100644 index ac4dc98..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/YouTube_Music.list +++ /dev/null @@ -1,3 +0,0 @@ -# > Youtube_Music -USER-AGENT,*YouTubeMusic* -USER-AGENT,*com.google.ios.youtubemusic* \ No newline at end of file diff --git a/base/rules/lhie1/Surge/Surge 3/Provider/Media/myTV_SUPER.list b/base/rules/lhie1/Surge/Surge 3/Provider/Media/myTV_SUPER.list deleted file mode 100644 index 6300356..0000000 --- a/base/rules/lhie1/Surge/Surge 3/Provider/Media/myTV_SUPER.list +++ /dev/null @@ -1,4 +0,0 @@ -# > myTV_SUPER -USER-AGENT,mytv* -DOMAIN-SUFFIX,mytvsuper.com -DOMAIN-SUFFIX,tvb.com \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 1112274..4bbfa67 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -61,6 +61,21 @@ void chkArg(int argc, char *argv[]) } } +void signal_handler(int sig) +{ + std::cerr<<"Interrupt signal "< &nodes) @@ -181,7 +181,7 @@ void explodeVmessConf(std::string content, std::string custom_port, int local_po json["vmess"][i]["security"] >> cipher; group = V2RAY_DEFAULT_GROUP; node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; - node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, tls, local_port); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, "", tls, local_port); break; case 3: //ss config json["vmess"][i]["id"] >> id; @@ -579,7 +579,7 @@ void explodeSocks(std::string link, std::string custom_port, nodeInfo &node) void explodeQuan(std::string quan, std::string custom_port, int local_port, nodeInfo &node) { 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, 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 configs, vArray; strTemp = regReplace(quan, "(.*?) = (.*)", "$1,$2"); configs = split(strTemp, ","); @@ -614,6 +614,8 @@ void explodeQuan(std::string quan, std::string custom_port, int local_port, node { if(strFind(headers[j], "Host: ")) host = headers[j].substr(6); + else if(strFind(headers[j], "Edge: ")) + edge = headers[j].substr(6); } } else if(itemName == "obfs" && itemVal == "ws") @@ -627,14 +629,14 @@ void explodeQuan(std::string quan, std::string custom_port, int local_port, node node.remarks = ps; node.server = add; node.port = to_int(port, 0); - node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, tls, local_port); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, edge, tls, local_port); } } void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, std::string custom_port, int local_port, nodeInfo &node) { Document json; - std::string type, remark, address, port, username, password, method, plugin, pluginopts, protocol, protoparam, obfs, obfsparam, id, aid, transprot, faketype, host, path, tls; + std::string type, remark, address, port, username, password, method, plugin, pluginopts, protocol, protoparam, obfs, obfsparam, id, aid, transprot, faketype, host, edge, path, tls; netch = urlsafe_base64_decode(netch.substr(8)); json.Parse(netch.data()); @@ -685,10 +687,11 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, std::string faketype = GetMember(json, "FakeType"); host = GetMember(json, "Host"); path = GetMember(json, "Path"); + edge = GetMember(json, "Edge"); tls = GetMember(json, "TLSSecure") == "true" ? "tls" : ""; node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.group = V2RAY_DEFAULT_GROUP; - node.proxyStr = vmessConstruct(address, port, faketype, id, aid, transprot, method, path, host, tls, local_port); + node.proxyStr = vmessConstruct(address, port, faketype, id, aid, transprot, method, path, host, edge, tls, local_port); } else if(type == "Socks5") { @@ -711,7 +714,7 @@ void explodeClash(Node yamlnode, std::string custom_port, int local_port, std::v Node singleproxy; unsigned int index = nodes.size(); 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 type = "none", id, aid = "0", net = "tcp", path, host, edge, tls; //vmess std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss std::string protocol, protoparam, obfs, obfsparam; //ssr std::string user; //socks @@ -736,13 +739,16 @@ void explodeClash(Node yamlnode, std::string custom_port, int local_port, std::v else tls.clear(); if(singleproxy["ws-headers"].IsDefined()) + { singleproxy["ws-headers"]["Host"] >> host; + singleproxy["ws-headers"]["Edge"] >> edge; + } else host.clear(); node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; - node.proxyStr = vmessConstruct(server, port, type, id, aid, net, cipher, path, host, tls, local_port); + node.proxyStr = vmessConstruct(server, port, type, id, aid, net, cipher, path, host, edge, tls, local_port); } else if(proxytype == "ss") { @@ -940,7 +946,7 @@ void explodeShadowrocket(std::string rocket, std::string custom_port, int local_ node.remarks = remarks; node.server = add; node.port = to_int(port, 0); - node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, tls, local_port); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, "", tls, local_port); } void explodeKitsunebi(std::string kit, std::string custom_port, int local_port, nodeInfo &node) @@ -985,14 +991,14 @@ void explodeKitsunebi(std::string kit, std::string custom_port, int local_port, node.remarks = remarks; node.server = add; node.port = to_int(port, 0); - node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, tls, local_port); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, "", tls, local_port); } bool explodeSurge(std::string surge, std::string custom_port, int local_port, std::vector &nodes, bool libev) { 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 id, net, tls, host, edge, path; //v2 std::string protocol, protoparam; //ssr std::string itemName, itemVal; std::vector configs, vArray, headers, header; @@ -1157,6 +1163,8 @@ bool explodeSurge(std::string surge, std::string custom_port, int local_port, st header = split(trim(y), ":"); if(header[0] == "Host") host = header[1]; + else if(header[0] == "Edge") + edge = header[1]; } } } @@ -1165,7 +1173,7 @@ bool explodeSurge(std::string surge, std::string custom_port, int local_port, st node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.group = V2RAY_DEFAULT_GROUP; - node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, tls, local_port); + node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, edge, tls, local_port); } else if(configs[0] == "http") //http proxy { @@ -1274,7 +1282,7 @@ bool explodeSurge(std::string surge, std::string custom_port, int local_port, st node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.group = V2RAY_DEFAULT_GROUP; - node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, tls, local_port); + node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, "", tls, local_port); } else continue; diff --git a/src/speedtestutil.h b/src/speedtestutil.h index d145ba9..8bcafcf 100644 --- a/src/speedtestutil.h +++ b/src/speedtestutil.h @@ -7,7 +7,7 @@ #include "misc.h" #include "nodeinfo.h" -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); +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 edge, std::string tls, int local_port); 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); 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); std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password); diff --git a/src/subexport.cpp b/src/subexport.cpp index 88568ac..db7c9fe 100644 --- a/src/subexport.cpp +++ b/src/subexport.cpp @@ -58,7 +58,7 @@ std::string hostnameToIPAddr(std::string host) } */ -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) +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 edge, std::string tls, int local_port) { if(!path.size()) path = "/"; @@ -90,6 +90,8 @@ std::string vmessConstruct(std::string add, std::string port, std::string type, writer.String(net.data()); writer.Key("Host"); writer.String(host.data()); + writer.Key("Edge"); + writer.String(edge.data()); if(net == "ws") { writer.Key("Path"); @@ -557,7 +559,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr 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 id, aid, transproto, faketype, host, edge, path, quicsecure, quicsecret; std::vector nodelist; bool tlssecure, replace_flag; string_array vArray, remarks_list, filtered_nodelist; @@ -637,6 +639,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr aid = GetMember(json, "AlterID"); transproto = GetMember(json, "TransferProtocol"); host = GetMember(json, "Host"); + edge = GetMember(json, "Edge"); path = GetMember(json, "Path"); tlssecure = GetMember(json, "TLSSecure") == "true"; singleproxy["type"] = "vmess"; @@ -651,6 +654,12 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr singleproxy["network"] = transproto; singleproxy["ws-path"] = path; singleproxy["ws-headers"]["Host"] = host; + singleproxy["headers"]["Host"] = host; + if(edge.size()) + { + singleproxy["ws-headers"]["Edge"] = edge; + singleproxy["headers"]["Edge"] = edge; + } } else if(transproto == "kcp" || transproto == "h2" || transproto == "quic") continue; @@ -662,7 +671,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr obfs = GetMember(json, "OBFS"); if(ext.filter_deprecated) { - if(method == "chacha20") + if(method == "chacha20" && !clashR) //the mainline core no longer supports chacha20, but clashR core still does continue; if(std::find(clashr_protocols.cbegin(), clashr_protocols.cend(), protocol) == clashr_protocols.cend()) continue; @@ -805,7 +814,7 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s 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 id, aid, transproto, faketype, host, edge, path, quicsecure, quicsecret; std::string output_nodelist; std::vector nodelist; unsigned short local_port = 1080; @@ -886,12 +895,15 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s aid = GetMember(json, "AlterID"); transproto = GetMember(json, "TransferProtocol"); host = GetMember(json, "Host"); + edge = GetMember(json, "Edge"); path = GetMember(json, "Path"); tlssecure = GetMember(json, "TLSSecure") == "true"; proxy = "vmess, " + hostname + ", " + port + ", username=" + id + ", tls=" + (tlssecure ? "true" : "false"); if(transproto == "ws") { proxy += ", ws=true, ws-path=" + path + ", ws-headers=Host:" + host; + if(edge.size()) + proxy += "|Edge:" + edge; } if(ext.skip_cert_verify) proxy += ", skip-cert-verify=1"; @@ -1317,7 +1329,7 @@ void netchToQuan(std::vector &nodes, INIReader &ini, std::vector nodelist; @@ -1369,6 +1381,7 @@ void netchToQuan(std::vector &nodes, INIReader &ini, std::vector &nodes, INIReader &ini, std::vector #include #include -#include +#include #include #include @@ -23,44 +23,9 @@ struct responseRoute std::vector responses; //for use of multi-thread -typedef std::lock_guard guarded_mutex; -int working_thread = 0, max_send_failure = 10; -bool SERVER_EXIT_FLAG = false; -std::mutex working_mutex, server_exit_flag_mutex; - -static inline void working_acc() -{ - guarded_mutex guard(working_mutex); - working_thread++; -} - -static inline void working_dec() -{ - guarded_mutex guard(working_mutex); - working_thread--; -} - -static inline int safe_read_working() -{ - int retVal; - guarded_mutex guard(working_mutex); - retVal = working_thread; - return retVal; -} - -static inline bool safe_read_server_exit_flag() -{ - bool retVal; - guarded_mutex guard(server_exit_flag_mutex); - retVal = SERVER_EXIT_FLAG; - return retVal; -} - -static inline void safe_set_server_exit_flag() -{ - guarded_mutex guard(server_exit_flag_mutex); - SERVER_EXIT_FLAG = true; -} +int max_send_failure = 10; +std::atomic_bool SERVER_EXIT_FLAG(false); +std::atomic_int working_thread(0) int sendall(SOCKET sock, std::string data) { @@ -214,7 +179,7 @@ int setTimeout(SOCKET s, int timeout) ret = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(int)); ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(int)); #else - struct timeval timeo = {0, timeout * 1000}; + struct timeval timeo = {timeout / 1000, (timeout % 1000) * 1000}; ret = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeo, sizeof(timeo)); ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeo, sizeof(timeo)); #endif @@ -224,7 +189,7 @@ int setTimeout(SOCKET s, int timeout) void handle_req(std::string request, int client_sock) { - working_acc(); + working_thread++; std::cerr<<"worker startup"<max_workers = 1; + return start_web_server_multi(args); +} + int start_web_server_multi(void *argv) { //log startup @@ -373,10 +350,10 @@ int start_web_server_multi(void *argv) //handle_req(buf, acc_socket); - while(safe_read_working() >= max_workers) + while(working_thread >= max_workers) { sleep(10); - if(safe_read_server_exit_flag()) + if(SERVER_EXIT_FLAG) break; } while(workers[worker_index].get_id() != std::thread::id()) diff --git a/src/webserver.h b/src/webserver.h index 50a3547..92c9369 100644 --- a/src/webserver.h +++ b/src/webserver.h @@ -16,5 +16,6 @@ struct listener_args void append_response(std::string method, std::string uri, std::string content_type, response_callback response); int start_web_server(void *argv); int start_web_server_multi(void *argv); +void stop_web_server(); #endif // WEBSERVER_H_INCLUDED diff --git a/src/webserver_libevent.cpp b/src/webserver_libevent.cpp index 9b38039..cc5abc5 100644 --- a/src/webserver_libevent.cpp +++ b/src/webserver_libevent.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #ifdef MALLOC_TRIM #include #endif // MALLOC_TRIM @@ -17,6 +18,7 @@ #include "socket.h" extern std::string user_agent_str; +std::atomic_bool SERVER_EXIT_FLAG(false); struct responseRoute { @@ -178,6 +180,7 @@ int start_web_server(void *argv) void* httpserver_dispatch(void *arg) { event_base_dispatch((struct event_base*)arg); + event_base_free((struct event_base*)arg); return NULL; } @@ -235,12 +238,13 @@ int start_web_server_multi(void *argv) return -1; pthread_t ths[nthreads]; + struct event_base *base[nthreads]; for (i = 0; i < nthreads; i++) { - struct event_base *base = event_init(); - if (base == NULL) + base[i] = event_init(); + if (base[i] == NULL) return -1; - struct evhttp *httpd = evhttp_new(base); + struct evhttp *httpd = evhttp_new(base[i]); if (httpd == NULL) return -1; ret = evhttp_accept_socket(httpd, nfd); @@ -249,16 +253,24 @@ int start_web_server_multi(void *argv) evhttp_set_allowed_methods(httpd, EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_OPTIONS); evhttp_set_gencb(httpd, OnReq, nullptr); - ret = pthread_create(&ths[i], NULL, httpserver_dispatch, base); + ret = pthread_create(&ths[i], NULL, httpserver_dispatch, base[i]); if (ret != 0) return -1; } - while(true) - sleep(10000); //block forever + while(!SERVER_EXIT_FLAG) + sleep(200); //block forever until receive stop signal + + for (i = 0; i < nthreads; i++) + event_base_loopbreak(base[i]); return 0; } +void stop_web_server() +{ + SERVER_EXIT_FLAG = true; +} + void append_response(std::string method, std::string uri, std::string content_type, response_callback response) { responseRoute rr;