From e8a822d010fc94668f8b755ae2a5cca7d7cd5831 Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Thu, 31 Oct 2019 13:18:40 +0800 Subject: [PATCH] First public version --- forcerule.yml | 2876 ++++++++++++++++++++++++++++++++++++++++ ini_reader.h | 711 ++++++++++ logger.cpp | 8 + logger.h | 35 + main.cpp | 241 ++++ misc.cpp | 776 +++++++++++ misc.h | 90 ++ nodeinfo.h | 17 + nodemanip.cpp | 108 ++ nodemanip.h | 11 + pref.ini | 139 ++ printout.h | 71 + rapidjson_extra.cpp | 56 + rapidjson_extra.h | 13 + simple_base.yml | 15 + socket.h | 56 + speedtestutil.cpp | 1558 ++++++++++++++++++++++ speedtestutil.h | 27 + subexport.cpp | 415 ++++++ subexport.h | 12 + webget.cpp | 57 + webget.h | 18 + webserver.cpp | 376 ++++++ webserver.h | 20 + webserver_libevent.cpp | 221 +++ yamlcpp_extra.h | 14 + 26 files changed, 7941 insertions(+) create mode 100644 forcerule.yml create mode 100644 ini_reader.h create mode 100644 logger.cpp create mode 100644 logger.h create mode 100644 main.cpp create mode 100644 misc.cpp create mode 100644 misc.h create mode 100644 nodeinfo.h create mode 100644 nodemanip.cpp create mode 100644 nodemanip.h create mode 100644 pref.ini create mode 100644 printout.h create mode 100644 rapidjson_extra.cpp create mode 100644 rapidjson_extra.h create mode 100644 simple_base.yml create mode 100644 socket.h create mode 100644 speedtestutil.cpp create mode 100644 speedtestutil.h create mode 100644 subexport.cpp create mode 100644 subexport.h create mode 100644 webget.cpp create mode 100644 webget.h create mode 100644 webserver.cpp create mode 100644 webserver.h create mode 100644 webserver_libevent.cpp create mode 100644 yamlcpp_extra.h diff --git a/forcerule.yml b/forcerule.yml new file mode 100644 index 0000000..54c8d95 --- /dev/null +++ b/forcerule.yml @@ -0,0 +1,2876 @@ +# HTTP 代理端口 +port: 7890 + +# SOCKS5 代理端口 +socks-port: 7891 + +# Linux 和 macOS 的 redir 代理端口 (如需使用此功能,请取消注释) +# redir-port: 7892 + +# 允许局域网的连接(可用来共享代理) +allow-lan: true + +# 规则模式:Rule(规则) / Global(全局代理)/ Direct(全局直连) +mode: Rule + +# 设置日志输出级别 (默认级别:silent,即不输出任何内容,以避免因日志内容过大而导致程序内存溢出)。 +# 5 个级别:silent / info / warning / error / debug。级别越高日志输出量越大,越倾向于调试,若需要请自行开启。 +log-level: info + +# clash 的 RESTful API +external-controller: 127.0.0.1:9090 + +# 您可以将静态网页资源(如 clash-dashboard)放置在一个目录中,clash 将会服务于 `${API}/ui` +# 参数应填写配置目录的相对路径或绝对路径。 +# external-ui: folder + +# RESTful API 的口令 (可选) +# secret: "" + +# DNS 设置 +dns: + enable: false + listen: 0.0.0.0:53 + ipv6: false + enhanced-mode: fake-ip + nameserver: + - 119.29.29.29 + - 114.114.114.114 + - 223.5.5.5 + + + +# 代理节点 +Proxy: +# Shadowsocks +- name: "1" + type: ss + server: 1.2.4.8 + port: 443 + cipher: chacha20-ietf-poly1305 + password: "password" + # udp: true + +# Shadowsocks + simple-obfs +- name: "2" + type: ss + server: 1.2.4.8 + port: 443 + cipher: chacha20-ietf-poly1305 + password: "password" + plugin: obfs + plugin-opts: + mode: tls # or http + # host: bing.com + +# Shadowsocks + v2ray-plugin +- name: "3" + type: ss + server: 1.2.4.8 + port: 443 + cipher: chacha20-ietf-poly1305 + password: "password" + plugin: v2ray-plugin + plugin-opts: + mode: websocket # no QUIC now + # tls: true # wss + # skip-cert-verify: true + # host: bing.com + # path: "/" + # mux: true + # headers: + # custom: value + +# VMess +- name: "4" + type: vmess + server: v2ray.cool + port: 443 + uuid: a3482e88-686a-4a58-8126-99c9df64b7bf + alterId: 64 + cipher: auto + # udp: true + # tls: true + # skip-cert-verify: true + # network: ws + # ws-path: /path + # ws-headers: + # Host: v2ray.com + + +# 代理组策略 +Proxy Group: +# 代理节点选择 +- { name: "Proxy", type: select, proxies: ["1", "2", "3","4"] } +# 油管 +- { name: "google", type: select, proxies: ["Proxy","1", "2", "3","4"] } +# netflix +- { name: "netflix", type: select, proxies: ["Proxy","1", "2", "3","4"] } +# 动画疯 +- { name: "动画疯", type: select, proxies: ["Proxy","1", "2", "3","4"] } +# 美区影视 +- { name: "美区影视", type: select, proxies: ["Proxy","1", "2", "3","4"] } +# fox+ +- { name: "fox+", type: select, proxies: ["Proxy","1", "2", "3","4"] } +# 白名单模式 PROXY,黑名单模式 DIRECT +- { name: "Final", type: select, proxies: ["Proxy","网易解锁", "DIRECT"] } +# Apple 服务代理 +- { name: "Apple", type: select, proxies: ["DIRECT", "Proxy"] } +# 国际媒体服务 +- { name: "Global_media", type: select, proxies: ["Proxy","网易解锁","1", "2", "3","4"] } +# 国内媒体服务 +- { name: "Domestic", type: select, proxies: ["DIRECT","网易解锁", "1", "2", "3","4"] } +#去广告 +- { name: "屏蔽广告", type: select, proxies: ["REJECT","网易解锁", "DIRECT"] } +#网易解锁 +- { name: "UnblockNeteaseMusic", type: select, proxies: ["网易解锁"] } +#Telegram +- { name: "Telegram", type: select, proxies: ["Proxy"] } + +#规则 +Rule: + +- DOMAIN-KEYWORD,netease,UnblockNeteaseMusic +# USER-AGENT,NeteaseMusic*,UnblockNeteaseMusic +# USER-AGENT,%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90*,UnblockNeteaseMusic +# USER-AGENT, %E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90*,UnblockNeteaseMusic +# USER-AGENT, %E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90**,UnblockNeteaseMusic +# USER-AGENT, NeteaseMusic**, UnblockNeteaseMusic +# USER-AGENT, 网易云音乐*, UnblockNeteaseMusic +# USER-AGENT, 网易云音乐**, UnblockNeteaseMusic +- DOMAIN-SUFFIX,music.126.net,UnblockNeteaseMusic +- DOMAIN-SUFFIX,163.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,music.163.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,interface.music.163.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,interface3.music.163.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,apm.music.163.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,apm3.music.163.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,man.netease.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,api.iplay.163.com,UnblockNeteaseMusic +- IP-CIDR,59.111.181.60/32,UnblockNeteaseMusic +- IP-CIDR,223.252.199.66/32,UnblockNeteaseMusic +- IP-CIDR,223.252.199.67/32,UnblockNeteaseMusic +- IP-CIDR,59.111.160.195/32,UnblockNeteaseMusic +- IP-CIDR,59.111.160.197/32,UnblockNeteaseMusic +- IP-CIDR,59.111.181.35/32,UnblockNeteaseMusic +- IP-CIDR,59.111.181.38/32,UnblockNeteaseMusic +- IP-CIDR,39.105.63.80/32,UnblockNeteaseMusic +- IP-CIDR,47.100.127.239/32,UnblockNeteaseMusic +- IP-CIDR,118.24.63.156/32,UnblockNeteaseMusic +- IP-CIDR,193.112.159.225/32,UnblockNeteaseMusic +- IP-CIDR,59.111.181.155/32,UnblockNeteaseMusic +- IP-CIDR,115.236.118.33/32,UnblockNeteaseMusic +- IP-CIDR, 59.111.128.0/17, UnblockNeteaseMusic +- IP-CIDR, 115.236.112.0/20,UnblockNeteaseMusic +- IP-CIDR, 223.252.192.0/19,UnblockNeteaseMusic +- DOMAIN-SUFFIX,ac.dun.163yun.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,mr.da.netease.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,crash.163.com,UnblockNeteaseMusic +- IP-CIDR,101.71.154.241/32,UnblockNeteaseMusic +- DOMAIN-SUFFIX,imap.163.com,UnblockNeteaseMusic +- DOMAIN-SUFFIX,isure.stream.qqmusic.qq.com,UnblockNeteaseMusic +- IP-CIDR,101.71.154.241/32,UnblockNeteaseMusic +- IP-CIDR,115.236.118.33/32,UnblockNeteaseMusic +- DOMAIN,music.163.com,UnblockNeteaseMusic +- DOMAIN,interface.music.163.com,UnblockNeteaseMusic +- DOMAIN,interface3.music.163.com,UnblockNeteaseMusic +- DOMAIN,apm.music.163.com,UnblockNeteaseMusic +- DOMAIN,apm3.music.163.com,UnblockNeteaseMusic +- DOMAIN,man.netease.com,UnblockNeteaseMusic +- DOMAIN,api.iplay.163.com,UnblockNeteaseMusic +- IP-CIDR,59.111.181.60/32,UnblockNeteaseMusic +- IP-CIDR,223.252.199.66/32,UnblockNeteaseMusic +- IP-CIDR,223.252.199.67/32,UnblockNeteaseMusic +- IP-CIDR,59.111.160.195/32,UnblockNeteaseMusic +- IP-CIDR,59.111.160.197/32,UnblockNeteaseMusic +- IP-CIDR,59.111.181.35/32,UnblockNeteaseMusic +- IP-CIDR,59.111.181.38/32,UnblockNeteaseMusic +- IP-CIDR,39.105.63.80/32,UnblockNeteaseMusic +- IP-CIDR,47.100.127.239/32,UnblockNeteaseMusic +- IP-CIDR,118.24.63.156/32,UnblockNeteaseMusic +- IP-CIDR,193.112.159.225/32,UnblockNeteaseMusic +- IP-CIDR,59.111.181.155/32,UnblockNeteaseMusic +- IP-CIDR,101.71.154.241/32,UnblockNeteaseMusic +- IP-CIDR,115.236.118.33/32,UnblockNeteaseMusic +# Internet Service Provider Hijacking 运营商劫持 +- DOMAIN-SUFFIX,17gouwuba.com,屏蔽广告 +- DOMAIN-SUFFIX,186078.com,屏蔽广告 +- DOMAIN-SUFFIX,189zj.cn,屏蔽广告 +- DOMAIN-SUFFIX,285680.com,屏蔽广告 +- DOMAIN-SUFFIX,3721zh.com,屏蔽广告 +- DOMAIN-SUFFIX,4336wang.cn,屏蔽广告 +- DOMAIN-SUFFIX,51chumoping.com,屏蔽广告 +- DOMAIN-SUFFIX,51mld.cn,屏蔽广告 +- DOMAIN-SUFFIX,51mypc.cn,屏蔽广告 +- DOMAIN-SUFFIX,58mingri.cn,屏蔽广告 +- DOMAIN-SUFFIX,58mingtian.cn,屏蔽广告 +- DOMAIN-SUFFIX,5vl58stm.com,屏蔽广告 +- DOMAIN-SUFFIX,6d63d3.com,屏蔽广告 +- DOMAIN-SUFFIX,7gg.cc,屏蔽广告 +- DOMAIN-SUFFIX,91veg.com,屏蔽广告 +- DOMAIN-SUFFIX,9s6q.cn,屏蔽广告 +- DOMAIN-SUFFIX,adsame.com,屏蔽广告 +- DOMAIN-SUFFIX,aiclk.com,屏蔽广告 +- DOMAIN-SUFFIX,akuai.top,屏蔽广告 +- DOMAIN-SUFFIX,atplay.cn,屏蔽广告 +- DOMAIN-SUFFIX,baiwanchuangyi.com,屏蔽广告 +- DOMAIN-SUFFIX,beerto.cn,屏蔽广告 +- DOMAIN-SUFFIX,beilamusi.com,屏蔽广告 +- DOMAIN-SUFFIX,benshiw.net,屏蔽广告 +- DOMAIN-SUFFIX,bianxianmao.com,屏蔽广告 +- DOMAIN-SUFFIX,bryonypie.com,屏蔽广告 +- DOMAIN-SUFFIX,cishantao.com,屏蔽广告 +- DOMAIN-SUFFIX,cszlks.com,屏蔽广告 +- DOMAIN-SUFFIX,cudaojia.com,屏蔽广告 +- DOMAIN-SUFFIX,dafapromo.com,屏蔽广告 +- DOMAIN-SUFFIX,daitdai.com,屏蔽广告 +- DOMAIN-SUFFIX,dsaeerf.com,屏蔽广告 +- DOMAIN-SUFFIX,dugesheying.com,屏蔽广告 +- DOMAIN-SUFFIX,dv8c1t.cn,屏蔽广告 +- DOMAIN-SUFFIX,echatu.com,屏蔽广告 +- DOMAIN-SUFFIX,erdoscs.com,屏蔽广告 +- DOMAIN-SUFFIX,fan-yong.com,屏蔽广告 +- DOMAIN-SUFFIX,feih.com.cn,屏蔽广告 +- DOMAIN-SUFFIX,fjlqqc.com,屏蔽广告 +- DOMAIN-SUFFIX,fkku194.com,屏蔽广告 +- DOMAIN-SUFFIX,freedrive.cn,屏蔽广告 +- DOMAIN-SUFFIX,gclick.cn,屏蔽广告 +- DOMAIN-SUFFIX,goufanli100.com,屏蔽广告 +- DOMAIN-SUFFIX,goupaoerdai.com,屏蔽广告 +- DOMAIN-SUFFIX,gouwubang.com,屏蔽广告 +- DOMAIN-SUFFIX,gzxnlk.com,屏蔽广告 +- DOMAIN-SUFFIX,haoshengtoys.com,屏蔽广告 +- DOMAIN-SUFFIX,hyunke.com,屏蔽广告 +- DOMAIN-SUFFIX,ichaosheng.com,屏蔽广告 +- DOMAIN-SUFFIX,ishop789.com,屏蔽广告 +- DOMAIN-SUFFIX,jdkic.com,屏蔽广告 +- DOMAIN-SUFFIX,jiubuhua.com,屏蔽广告 +- DOMAIN-SUFFIX,jwg365.cn,屏蔽广告 +- DOMAIN-SUFFIX,kawo77.com,屏蔽广告 +- DOMAIN-SUFFIX,kualianyingxiao.cn,屏蔽广告 +- DOMAIN-SUFFIX,kumihua.com,屏蔽广告 +- DOMAIN-SUFFIX,ltheanine.cn,屏蔽广告 +- DOMAIN-SUFFIX,maipinshangmao.com,屏蔽广告 +- DOMAIN-SUFFIX,minisplat.cn,屏蔽广告 +- DOMAIN-SUFFIX,mkitgfs.com,屏蔽广告 +- DOMAIN-SUFFIX,mlnbike.com,屏蔽广告 +- DOMAIN-SUFFIX,mobjump.com,屏蔽广告 +- DOMAIN-SUFFIX,nbkbgd.cn,屏蔽广告 +- DOMAIN-SUFFIX,newapi.com,屏蔽广告 +- DOMAIN-SUFFIX,pinzhitmall.com,屏蔽广告 +- DOMAIN-SUFFIX,poppyta.com,屏蔽广告 +- DOMAIN-SUFFIX,qianchuanghr.com,屏蔽广告 +- DOMAIN-SUFFIX,qichexin.com,屏蔽广告 +- DOMAIN-SUFFIX,qinchugudao.com,屏蔽广告 +- DOMAIN-SUFFIX,quanliyouxi.cn,屏蔽广告 +- DOMAIN-SUFFIX,qutaobi.com,屏蔽广告 +- DOMAIN-SUFFIX,ry51w.cn,屏蔽广告 +- DOMAIN-SUFFIX,sg536.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifubo.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifuce.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifuda.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifufu.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifuge.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifugu.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifuhe.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifuhu.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifuji.cn,屏蔽广告 +- DOMAIN-SUFFIX,sifuka.cn,屏蔽广告 +- DOMAIN-SUFFIX,smgru.net,屏蔽广告 +- DOMAIN-SUFFIX,taoggou.com,屏蔽广告 +- DOMAIN-SUFFIX,tcxshop.com,屏蔽广告 +- DOMAIN-SUFFIX,tjqonline.cn,屏蔽广告 +- DOMAIN-SUFFIX,topitme.com,屏蔽广告 +- DOMAIN-SUFFIX,tt3sm4.cn,屏蔽广告 +- DOMAIN-SUFFIX,tuia.cn,屏蔽广告 +- DOMAIN-SUFFIX,tuipenguin.com,屏蔽广告 +- DOMAIN-SUFFIX,tuitiger.com,屏蔽广告 +- DOMAIN-SUFFIX,websd8.com,屏蔽广告 +- DOMAIN-SUFFIX,wx16999.com,屏蔽广告 +- DOMAIN-SUFFIX,xiaohuau.xyz,屏蔽广告 +- DOMAIN-SUFFIX,yinmong.com,屏蔽广告 +- DOMAIN-SUFFIX,yiqifa.com,屏蔽广告 +- DOMAIN-SUFFIX,yitaopt.com,屏蔽广告 +- DOMAIN-SUFFIX,yjqiqi.com,屏蔽广告 +- DOMAIN-SUFFIX,yukhj.com,屏蔽广告 +- DOMAIN-SUFFIX,zhaozecheng.cn,屏蔽广告 +- DOMAIN-SUFFIX,zhenxinet.com,屏蔽广告 +- DOMAIN-SUFFIX,zlne800.com,屏蔽广告 +- DOMAIN-SUFFIX,zunmi.cn,屏蔽广告 +- DOMAIN-SUFFIX,zzd6.com,屏蔽广告 + +# Infamous 声名狼藉 +- DOMAIN-SUFFIX,kuaizip.com,屏蔽广告 +- DOMAIN-SUFFIX,mackeeper.com,屏蔽广告 +# > Adobe 奥多比 +- DOMAIN-SUFFIX,flash.cn,屏蔽广告 +- DOMAIN,geo2.adobe.com,屏蔽广告 +# > CJ Marketing 思杰马克丁软件 +- DOMAIN-SUFFIX,4009997658.com,屏蔽广告 +- DOMAIN-SUFFIX,abbyychina.com,屏蔽广告 +- DOMAIN-SUFFIX,bartender.cc,屏蔽广告 +- DOMAIN-SUFFIX,betterzip.net,屏蔽广告 +- DOMAIN-SUFFIX,beyondcompare.cc,屏蔽广告 +- DOMAIN-SUFFIX,bingdianhuanyuan.cn,屏蔽广告 +- DOMAIN-SUFFIX,chemdraw.com.cn,屏蔽广告 +- DOMAIN-SUFFIX,cjmakeding.com,屏蔽广告 +- DOMAIN-SUFFIX,cjmkt.com,屏蔽广告 +- DOMAIN-SUFFIX,codesoftchina.com,屏蔽广告 +- DOMAIN-SUFFIX,coreldrawchina.com,屏蔽广告 +- DOMAIN-SUFFIX,crossoverchina.com,屏蔽广告 +- DOMAIN-SUFFIX,dongmansoft.com,屏蔽广告 +- DOMAIN-SUFFIX,earmasterchina.cn,屏蔽广告 +- DOMAIN-SUFFIX,easyrecoverychina.com,屏蔽广告 +- DOMAIN-SUFFIX,ediuschina.com,屏蔽广告 +- DOMAIN-SUFFIX,flstudiochina.com,屏蔽广告 +- DOMAIN-SUFFIX,formysql.com,屏蔽广告 +- DOMAIN-SUFFIX,guitarpro.cc,屏蔽广告 +- DOMAIN-SUFFIX,huishenghuiying.com.cn,屏蔽广告 +- DOMAIN-SUFFIX,hypersnap.net,屏蔽广告 +- DOMAIN-SUFFIX,iconworkshop.cn,屏蔽广告 +- DOMAIN-SUFFIX,imindmap.cc,屏蔽广告 +- DOMAIN-SUFFIX,jihehuaban.com.cn,屏蔽广告 +- DOMAIN-SUFFIX,keyshot.cc,屏蔽广告 +- DOMAIN-SUFFIX,kingdeecn.cn,屏蔽广告 +- DOMAIN-SUFFIX,logoshejishi.com,屏蔽广告 +- DOMAIN-SUFFIX,luping.net.cn,屏蔽广告 +- DOMAIN-SUFFIX,mairuan.cn,屏蔽广告 +- DOMAIN-SUFFIX,mairuan.com,屏蔽广告 +- DOMAIN-SUFFIX,mairuan.com.cn,屏蔽广告 +- DOMAIN-SUFFIX,mairuan.net,屏蔽广告 +- DOMAIN-SUFFIX,mairuanwang.com,屏蔽广告 +- DOMAIN-SUFFIX,makeding.com,屏蔽广告 +- DOMAIN-SUFFIX,mathtype.cn,屏蔽广告 +- DOMAIN-SUFFIX,mindmanager.cc,屏蔽广告 +- DOMAIN-SUFFIX,mindmanager.cn,屏蔽广告 +- DOMAIN-SUFFIX,mindmapper.cc,屏蔽广告 +- DOMAIN-SUFFIX,mycleanmymac.com,屏蔽广告 +- DOMAIN-SUFFIX,nicelabel.cc,屏蔽广告 +- DOMAIN-SUFFIX,ntfsformac.cc,屏蔽广告 +- DOMAIN-SUFFIX,ntfsformac.cn,屏蔽广告 +- DOMAIN-SUFFIX,overturechina.com,屏蔽广告 +- DOMAIN-SUFFIX,passwordrecovery.cn,屏蔽广告 +- DOMAIN-SUFFIX,pdfexpert.cc,屏蔽广告 +- DOMAIN-SUFFIX,photozoomchina.com,屏蔽广告 +- DOMAIN-SUFFIX,shankejingling.com,屏蔽广告 +- DOMAIN-SUFFIX,ultraiso.net,屏蔽广告 +- DOMAIN-SUFFIX,vegaschina.cn,屏蔽广告 +- DOMAIN-SUFFIX,xmindchina.net,屏蔽广告 +- DOMAIN-SUFFIX,xshellcn.com,屏蔽广告 +- DOMAIN-SUFFIX,yihuifu.cn,屏蔽广告 +- DOMAIN-SUFFIX,yuanchengxiezuo.com,屏蔽广告 +- DOMAIN-SUFFIX,zbrushcn.com,屏蔽广告 +- DOMAIN-SUFFIX,zhzzx.com,屏蔽广告 + +- DOMAIN-KEYWORD,adservice,屏蔽广告 +- DOMAIN-KEYWORD,analytics,屏蔽广告 +- DOMAIN-KEYWORD,analysis,屏蔽广告 + +- DOMAIN,42trck.com,屏蔽广告 +- DOMAIN,51.la,屏蔽广告 +- DOMAIN,adcolony.com,屏蔽广告 +- DOMAIN,adinfuse.com,屏蔽广告 +- DOMAIN,adjust.com,屏蔽广告 +- DOMAIN,adjust.io,屏蔽广告 +- DOMAIN,admaster.com.cn,屏蔽广告 +- DOMAIN,admob.com,屏蔽广告 +- DOMAIN,adnyg.com,屏蔽广告 +- DOMAIN,adsensor.org,屏蔽广告 +- DOMAIN,adtarget.tech,屏蔽广告 +- DOMAIN,adthor.com,屏蔽广告 +- DOMAIN,adwhirl.com,屏蔽广告 +- DOMAIN,amazon-adsystem.com,屏蔽广告 +- DOMAIN,analysys.cn,屏蔽广告 +- DOMAIN,app-adforce.jp,屏蔽广告 +- DOMAIN,appadhoc.com,屏蔽广告 +- DOMAIN,appads.com,屏蔽广告 +- DOMAIN,appier.net,屏蔽广告 +- DOMAIN,applift.com,屏蔽广告 +- DOMAIN,appsflyer.com,屏蔽广告 +- DOMAIN,apsalar.com,屏蔽广告 +- DOMAIN,apxadtracking.net,屏蔽广告 +- DOMAIN,axonix.com,屏蔽广告 +- DOMAIN,cloudmobi.net,屏蔽广告 +- DOMAIN,cnzz.com,屏蔽广告 +- DOMAIN,ctrmi.com,屏蔽广告 +- DOMAIN,flurry.com,屏蔽广告 +- DOMAIN,go2cloud.org,屏蔽广告 +- DOMAIN,growingio.com,屏蔽广告 +- DOMAIN,haloapps.com,屏蔽广告 +- DOMAIN,inmobi.cn,屏蔽广告 +- DOMAIN,inmobi.com,屏蔽广告 +- DOMAIN,inmobi.net,屏蔽广告 +- DOMAIN,inmobicdn.cn,屏蔽广告 +- DOMAIN,irs01.com,屏蔽广告 +- DOMAIN,iskyworker.com,屏蔽广告 +- DOMAIN,kochava.com,屏蔽广告 +- DOMAIN,leadboltmobile.net,屏蔽广告 +- DOMAIN,lenzmx.com,屏蔽广告 +- DOMAIN,liveadvert.com,屏蔽广告 +- DOMAIN,lnk0.com,屏蔽广告 +- DOMAIN,lnk8.cn,屏蔽广告 +- DOMAIN,localytics.com,屏蔽广告 +- DOMAIN,measurementapi.com,屏蔽广告 +- DOMAIN,medialytics.com,屏蔽广告 +- DOMAIN,miaozhen.com,屏蔽广告 +- DOMAIN,mobclix.com,屏蔽广告 +- DOMAIN,mopub.com,屏蔽广告 +- DOMAIN,onelink.me,屏蔽广告 +- DOMAIN,qchannel01.cn,屏蔽广告 +- DOMAIN,rayjump.com,屏蔽广告 +- DOMAIN,rubiconproject.com,屏蔽广告 +- DOMAIN,scorecardresearch.com,屏蔽广告 +- DOMAIN,sdkclick.com,屏蔽广告 +- DOMAIN,shuzilm.cn,屏蔽广告 +- DOMAIN,smaato.net,屏蔽广告 +- DOMAIN,smartadserver.com,屏蔽广告 +- DOMAIN,smartnews-ads.com,屏蔽广告 +- DOMAIN,tagtic.cn,屏蔽广告 +- DOMAIN,tanv.com,屏蔽广告 +- DOMAIN,tanx.com,屏蔽广告 +- DOMAIN,trafficjunky.net,屏蔽广告 +- DOMAIN,uri6.com,屏蔽广告 +- DOMAIN,voicefive.com,屏蔽广告 +- DOMAIN,vungle.com,屏蔽广告 +- DOMAIN,wedolook.com,屏蔽广告 +- DOMAIN,xdrig.com,屏蔽广告 + +- DOMAIN,ad.daum.net,屏蔽广告 +- DOMAIN,track.xiachufang.com,屏蔽广告 +- DOMAIN,abema-adx.ameba.jp,屏蔽广告 +- DOMAIN,ad.12306.cn,屏蔽广告 +- DOMAIN,ad.51wnl-cq.com,屏蔽广告 +- DOMAIN,ad.caiyunapp.com,屏蔽广告 +- DOMAIN,ad.huajiao.com,屏蔽广告 +- DOMAIN,ad.hzyoka.com,屏蔽广告 +- DOMAIN,ad.jiemian.com,屏蔽广告 +- DOMAIN,ad.qingting.fm,屏蔽广告 +- DOMAIN,ad.wappalyzer.com,屏蔽广告 +- DOMAIN,ad-cn.jovcloud.com,屏蔽广告 +- DOMAIN,adextra.51wnl-cq.com,屏蔽广告 +- DOMAIN,ads.adadapted.com,屏蔽广告 +- DOMAIN,ads.daydaycook.com.cn,屏蔽广告 +- DOMAIN,ads.weilitoutiao.net,屏蔽广告 +- DOMAIN,adsapi.manhuaren.com,屏蔽广告 +- DOMAIN,adsdk.dmzj.com,屏蔽广告 +- DOMAIN,adserver.pandora.com,屏蔽广告 +- DOMAIN,adui.tg.meitu.com,屏蔽广告 +- DOMAIN,adv.bandi.so,屏蔽广告 +- DOMAIN,adx.hupu.com,屏蔽广告 +- DOMAIN,adx-api.hupu.com,屏蔽广告 +- DOMAIN,adxserver.ad.cmvideo.cn,屏蔽广告 +- DOMAIN,app-ad.variflight.com,屏蔽广告 +- DOMAIN,applog.mobike.com,屏蔽广告 +- DOMAIN,appnext.hs.llnwd.net,屏蔽广告 +- DOMAIN,appnext-a.akamaihd.net,屏蔽广告 +- DOMAIN,ggs.myzaker.com,屏蔽广告 +- DOMAIN,itad.linetv.tw,屏蔽广告 +- DOMAIN,ja.chushou.tv,屏蔽广告 +- DOMAIN,mads.suning.com,屏蔽广告 +- DOMAIN,mobileads.msn.com,屏蔽广告 +- DOMAIN,mopnativeadv.037201.com,屏蔽广告 +- DOMAIN,nativeadv.dftoutiao.com,屏蔽广告 +- DOMAIN,optimus-ads.amap.com,屏蔽广告 +- DOMAIN,sugar.zhihu.com,屏蔽广告 +- DOMAIN,track.tiara.daum.net,屏蔽广告 +- DOMAIN,track.tiara.kakao.com,屏蔽广告 +- DOMAIN,trackapp.guahao.cn,屏蔽广告 +- DOMAIN,traffic.mogujie.com,屏蔽广告 +- DOMAIN,wmlog.meituan.com,屏蔽广告 + +- DOMAIN,adshow.58.com,屏蔽广告 +- DOMAIN,track.58.com,屏蔽广告 +- DOMAIN,tracklog.58.com,屏蔽广告 +- DOMAIN,iadsdk.apple.com,屏蔽广告 +- DOMAIN,ads.internal.unity3d.com,屏蔽广告 +- DOMAIN,ads.prd.ie.internal.unity3d.com,屏蔽广告 +- DOMAIN,unityads.unity3d.com,屏蔽广告 +- DOMAIN,acs4baichuan.m.taobao.com,屏蔽广告 +- DOMAIN,adash.m.taobao.com,屏蔽广告 +- DOMAIN,adash.man.aliyuncs.com,屏蔽广告 +- DOMAIN,adashbc.ut.taobao.com,屏蔽广告 +- DOMAIN,adash-c.ut.taobao.com,屏蔽广告 +- DOMAIN,adashxgc.ut.taobao.com,屏蔽广告 +- DOMAIN,adashx4yt.m.taobao.com,屏蔽广告 +- DOMAIN,nbsdk-baichuan.alicdn.com,屏蔽广告 +- DOMAIN,tunion-api.m.taobao.com,屏蔽广告 + +- DOMAIN,adproxy.autohome.com.cn,屏蔽广告 +- DOMAIN,rd.autohome.com.cn,屏蔽广告 +- DOMAIN,al.autohome.com.cn,屏蔽广告 +- DOMAIN,applogapi.autohome.com.cn,屏蔽广告 + + +- DOMAIN,baidustatic.com,屏蔽广告 +- DOMAIN,cpro.baidu.com,屏蔽广告 +- DOMAIN,pos.baidu.com,屏蔽广告 +- DOMAIN,afd.baidu.com,屏蔽广告 +- DOMAIN,als.baidu.com,屏蔽广告 +- DOMAIN,duclick.baidu.com,屏蔽广告 +- DOMAIN,hm.baidu.com,屏蔽广告 +- DOMAIN,hmma.baidu.com,屏蔽广告 +- DOMAIN,mobads.baidu.com,屏蔽广告 +- DOMAIN,mobads-logs.baidu.com,屏蔽广告 +- DOMAIN,nsclick.baidu.com,屏蔽广告 + +- DOMAIN,applog.musical.ly,屏蔽广告 +- DOMAIN,track.toutiao.com,屏蔽广告 +- DOMAIN,xlog.snssdk.com,屏蔽广告 +- DOMAIN,xlog-va.byteoversea.com,屏蔽广告 + +- DOMAIN,adx.yiche.com,屏蔽广告 +- DOMAIN,log.ycapp.yiche.com,屏蔽广告 +- DOMAIN,advertise.baicizhan.org,屏蔽广告 +- DOMAIN,advertise.baicizhan.com,屏蔽广告 + + +- DOMAIN,galaxy.bjcathay.com,屏蔽广告 +- DOMAIN,mdrecv.app.cntvwb.cn,屏蔽广告 +- DOMAIN,sdapprecv.app.cntvwb.cn,屏蔽广告 +- DOMAIN,vdapprecv.app.cntvwb.cn,屏蔽广告 + +- DOMAIN,admarket.21cn.com,屏蔽广告 +- DOMAIN,adshows.21cn.com,屏蔽广告 + +- DOMAIN,atrace.chelaile.net.cn,屏蔽广告 +- DOMAIN,logs.chelaile.net.cn,屏蔽广告 +- DOMAIN,doubleclick.net,屏蔽广告 +- DOMAIN,googleadservices.com,屏蔽广告 +- DOMAIN,googleadsserving.cn,屏蔽广告 +- DOMAIN,googlesyndication.com,屏蔽广告 +- DOMAIN,googletagmanager.com,屏蔽广告 +- DOMAIN,googletagservices.com,屏蔽广告 +- DOMAIN,da.mgtv.com,屏蔽广告 +- DOMAIN,da.hunantv.com,屏蔽广告 +- DOMAIN,log.hunantv.com,屏蔽广告 +- DOMAIN,log.v2.hunantv.com,屏蔽广告 +- DOMAIN,v2.log.hunantv.com,屏蔽广告 +- DOMAIN,ifacelog.iqiyi.com,屏蔽广告 +- DOMAIN,msg.71.am,屏蔽广告 +- DOMAIN,msg.qy.net,屏蔽广告 +- DOMAIN,t7z.cupid.iqiyi.com,屏蔽广告 +# > Ifeng +- DOMAIN,deliver.ifeng.com,屏蔽广告 +- DOMAIN,api.newad.ifeng.com,屏蔽广告 +- DOMAIN,ifengad.3g.ifeng.com,屏蔽广告 +# (K) +# > KuGou and Kuwo +- DOMAIN,adserviceretry.kugou.com,屏蔽广告 +- DOMAIN,ads.service.kugou.com,屏蔽广告 +- DOMAIN,adsfile.bssdlbig.kugou.com,屏蔽广告 +- DOMAIN,g.koowo.com,屏蔽广告 +- DOMAIN,log.stat.kugou.com,屏蔽广告 +- DOMAIN,log.web.kugou.com,屏蔽广告 +- DOMAIN,log.kuwo.cn,屏蔽广告 +- DOMAIN,kgmobilestat.kugou.com,屏蔽广告 +- DOMAIN,kgmobilestatbak.kugou.com,屏蔽广告 +- DOMAIN,mobilelog.kugou.com,屏蔽广告 +- DOMAIN,mobilead.kuwo.cn,屏蔽广告 +- DOMAIN,rich.kuwo.cn,屏蔽广告 +# > Kingsoft +- DOMAIN,ad-stat.ksosoft.com,屏蔽广告 +- DOMAIN,img.auction-ads.wpscdn.cn,屏蔽广告 +- DOMAIN,counter.kingsoft.com,屏蔽广告 +- DOMAIN,counter.ksosoft.com,屏蔽广告 +- DOMAIN,minfo.wps.cn,屏蔽广告 +- DOMAIN,mobad.ijinshan.com,屏蔽广告 +- DOMAIN,ups.ksmobile.net,屏蔽广告 +- DOMAIN,ws.ksmobile.net,屏蔽广告 +- DOMAIN,webp2p.letv.com,屏蔽广告 +- DOMAIN,ark.letv.com,屏蔽广告 +- DOMAIN,emma-414870e223.huodonghezi.com,屏蔽广告 +- DOMAIN,g3.letv.com,屏蔽广告 +- DOMAIN,n.mark.letv.com,屏蔽广告 +- DOMAIN,ad.intl.xiaomi.com,屏蔽广告 +- DOMAIN,ad.xiaomi.com,屏蔽广告 +- DOMAIN,admob.xiaomi.com,屏蔽广告 +- DOMAIN,tracking.miui.com,屏蔽广告 +- DOMAIN,adv.sec.intl.miui.com,屏蔽广告 +- DOMAIN,adv.sec.miui.com,屏蔽广告 +- DOMAIN,data.mistat.xiaomi.com,屏蔽广告 +- DOMAIN,tracking.intl.miui.com,屏蔽广告 +- DOMAIN,ad.api.moji.com,屏蔽广告 +- DOMAIN,adlaunch.moji.com,屏蔽广告 +- DOMAIN,ads.mojicdn.com,屏蔽广告 +- DOMAIN,v1.log.moji.com,屏蔽广告 +- DOMAIN,ad.bn.netease.com,屏蔽广告 +- DOMAIN,ad.yixin.im,屏蔽广告 +- DOMAIN,admusicpic.music.126.net,屏蔽广告 +- DOMAIN,iadmat.nosdn.127.net,屏蔽广告 +- DOMAIN,iadmusicmat.music.126.net,屏蔽广告 +- DOMAIN,iadmusicmatvideo.music.126.net,屏蔽广告 +- DOMAIN,impservice.dictapp.youdao.com,屏蔽广告 +- DOMAIN,impservice.youdao.com,屏蔽广告 +- DOMAIN,log.yex.youdao.com,屏蔽广告 +- DOMAIN,log-yex.youdao.com,屏蔽广告 +- DOMAIN,n.3g.163.com,屏蔽广告 +- DOMAIN,nex.163.com,屏蔽广告 +- DOMAIN,yt-adp.nosdn.127.net,屏蔽广告 +- DOMAIN,ads.aplus.pptv.com,屏蔽广告 +- DOMAIN,ads.aplusapi.pptv.com,屏蔽广告 +- DOMAIN,asimgs.pplive.cn,屏蔽广告 +- DOMAIN,de.as.pptv.com,屏蔽广告 +- DOMAIN,regist.fotoable.com,屏蔽广告 +- DOMAIN,cdn.adapi.fotoable.com,屏蔽广告 +- DOMAIN,adnew.wifi8.com,屏蔽广告 +- DOMAIN,adfile.wifi8.com,屏蔽广告 +- DOMAIN,adimg.vue.weibo.com,屏蔽广告 +- DOMAIN,u1.img.mobile.sina.cn,屏蔽广告 +- DOMAIN,sax.sina.com.cn,屏蔽广告 +- DOMAIN,saxs.sina.com.cn,屏蔽广告 +- DOMAIN,saxn.sina.com.cn,屏蔽广告 +- DOMAIN,ads.sohu.com,屏蔽广告 +- DOMAIN,aty.sohu.com,屏蔽广告 +- DOMAIN,imp.optaim.com,屏蔽广告 +- DOMAIN,v2.reachmax.cn,屏蔽广告 +- DOMAIN,track.sohu.com,屏蔽广告 +- DOMAIN,hui.sohu.com,屏蔽广告 +- DOMAIN,bugly.qq.com,屏蔽广告 +- DOMAIN,e.qq.com,屏蔽广告 +- DOMAIN,gdt.qq.com,屏蔽广告 +- DOMAIN,l.qq.com,屏蔽广告 +- DOMAIN,rqd.qq.com,屏蔽广告 +- DOMAIN,adsmind.tc.qq.com,屏蔽广告 +- DOMAIN,btrace.qq.com,屏蔽广告 +- DOMAIN,mtrace.qq.com,屏蔽广告 +- DOMAIN,oth.eve.mdt.qq.com,屏蔽广告 +- DOMAIN,pgdt.gtimg.cn,屏蔽广告 +- DOMAIN,pingma.qq.com,屏蔽广告 +- DOMAIN,pingtcss.qq.com,屏蔽广告 +- DOMAIN,splashqqlive.gtimg.com,屏蔽广告 +- DOMAIN,tajs.qq.com,屏蔽广告 +- DOMAIN,wxsnsdy.wxs.qq.com,屏蔽广告 +- DOMAIN,wxsnsdythumb.wxs.qq.com,屏蔽广告 +- DOMAIN,imgadpai.thepaper.cn,屏蔽广告 +- DOMAIN,admonitor.thepaper.cn,屏蔽广告 +- DOMAIN,adsp.xunlei.com,屏蔽广告 +- DOMAIN,etl.xlmc.sandai.net,屏蔽广告 +- DOMAIN,adm.10jqka.com.cn,屏蔽广告 +- DOMAIN,stat.10jqka.com.cn,屏蔽广告 +- DOMAIN,ad-analysis.pconline.com.cn,屏蔽广告 +- DOMAIN,iad0ssl.pcauto.com.cn,屏蔽广告 +- DOMAIN,iad0ssl.pconline.com.cn,屏蔽广告 +- DOMAIN,imgad0.pcauto.com.cn,屏蔽广告 +- DOMAIN,imgad0.pconline.com.cn,屏蔽广告 +- DOMAIN,ivy.pchouse.com.cn,屏蔽广告 +- DOMAIN,adtrack.ucweb.com,屏蔽广告 +- DOMAIN,applogios.uc.cn,屏蔽广告 +- DOMAIN,track.uc.cn,屏蔽广告 +- DOMAIN,alog.umeng.com,屏蔽广告 +- DOMAIN,alog.umengcloud.com,屏蔽广告 +- DOMAIN,ar.umeng.com,屏蔽广告 +- DOMAIN,plbslog.umeng.com,屏蔽广告 +- DOMAIN,ulogs.umeng.com,屏蔽广告 +- DOMAIN,ulogs.umengcloud.com,屏蔽广告 +- DOMAIN,a.wkanx.com,屏蔽广告 +- DOMAIN,cwx.lianwangtech.com,屏蔽广告 +- DOMAIN,c1wx.lianwangtech.com,屏蔽广告 +- DOMAIN,ad.ximalaya.com,屏蔽广告 +- DOMAIN,adse.ximalaya.com,屏蔽广告 +- DOMAIN,adse.wsa.ximalaya.com,屏蔽广告 +- DOMAIN,adbehavior.wsa.ximalaya.com,屏蔽广告 +- DOMAIN,apm-track.xiaohongshu.com,屏蔽广告 +- DOMAIN,t-ads.xiaohongshu.com,屏蔽广告 +- DOMAIN,atm.youku.com,屏蔽广告 +- DOMAIN,ad.mobile.youku.com,屏蔽广告 +- DOMAIN,iyes.youku.com,屏蔽广告 +- DOMAIN,apppv.zol.com.cn,屏蔽广告 +- DOMAIN,pvnapp.zol.com.cn,屏蔽广告 +- DOMAIN-KEYWORD,epochtimes,屏蔽广告 +- DOMAIN,881903.com,屏蔽广告 +- DOMAIN,aboluowang.com,屏蔽广告 +- DOMAIN,bannedbook.org,屏蔽广告 +- DOMAIN,bldaily.com,屏蔽广告 +- DOMAIN,china21.org,屏蔽广告 +- DOMAIN,chinaaffairs.org,屏蔽广告 +- DOMAIN,dajiyuan.com,屏蔽广告 +- DOMAIN,dalianmeng.org,屏蔽广告 +- DOMAIN,dkn.tv,屏蔽广告 +- DOMAIN,dongtaiwang.com,屏蔽广告 +- DOMAIN,edoors.com,屏蔽广告 +- DOMAIN,epochweekly.com,屏蔽广告 +- DOMAIN,falundafa.org,屏蔽广告 +- DOMAIN,fgmtv.org,屏蔽广告 +- DOMAIN,gardennetworks.com,屏蔽广告 +- DOMAIN,gongyiluntan.org,屏蔽广告 +- DOMAIN,gpass1.com,屏蔽广告 +- DOMAIN,hrichina.org,屏蔽广告 +- DOMAIN,huanghuagang.org,屏蔽广告 +- DOMAIN,internetfreedom.org,屏蔽广告 +- DOMAIN,kanzhongguo.com,屏蔽广告 +- DOMAIN,lagranepoca.com,屏蔽广告 +- DOMAIN,mh4u.org,屏蔽广告 +- DOMAIN,mhradio.org,屏蔽广告 +- DOMAIN,minghui.org,屏蔽广告 +- DOMAIN,newrealmstudios.ca,屏蔽广告 +- DOMAIN,ntdtv.com,屏蔽广告 +- DOMAIN,ogate.org,屏蔽广告 +- DOMAIN,open.com.hk,屏蔽广告 +- DOMAIN,organcare.org.tw,屏蔽广告 +- DOMAIN,qxbbs.org,屏蔽广告 +- DOMAIN,renminbao.com,屏蔽广告 +- DOMAIN,secretchina.com,屏蔽广告 +- DOMAIN,shenyun.com,屏蔽广告 +- DOMAIN,shenyunperformingarts.org,屏蔽广告 +- DOMAIN,shenzhoufilm.com,屏蔽广告 +- DOMAIN,soundofhope.org,屏蔽广告 +- DOMAIN,theepochtimes.com,屏蔽广告 +- DOMAIN,tiandixing.org,屏蔽广告 +- DOMAIN,tuidang.org,屏蔽广告 +- DOMAIN,velkaepocha.sk,屏蔽广告 +- DOMAIN,watchinese.com,屏蔽广告 +- DOMAIN,wixsite.com,屏蔽广告 +- DOMAIN,wujie.net,屏蔽广告 +- DOMAIN,wujieliulan.com,屏蔽广告 +- DOMAIN,xinsheng.net,屏蔽广告 +- DOMAIN,zhengjian.org,屏蔽广告 +- DOMAIN,zhuichaguoji.org,屏蔽广告 +# › AD Block KEYWORD +- DOMAIN-KEYWORD,admarvel,屏蔽广告 +- DOMAIN-KEYWORD,admaster,屏蔽广告 +- DOMAIN-KEYWORD,adsage,屏蔽广告 +- DOMAIN-KEYWORD,adsmogo,屏蔽广告 +- DOMAIN-KEYWORD,adsrvmedia,屏蔽广告 +- DOMAIN-KEYWORD,adwords,屏蔽广告 +- DOMAIN-KEYWORD,domob,屏蔽广告 +- DOMAIN-KEYWORD,duomeng,屏蔽广告 +- DOMAIN-KEYWORD,dwtrack,屏蔽广告 +- DOMAIN-KEYWORD,guanggao,屏蔽广告 +- DOMAIN-KEYWORD,lianmeng,屏蔽广告 +- DOMAIN-KEYWORD,omgmta,屏蔽广告 +- DOMAIN-KEYWORD,openx,屏蔽广告 +- DOMAIN-KEYWORD,partnerad,屏蔽广告 +- DOMAIN-KEYWORD,pingfore,屏蔽广告 +- DOMAIN-KEYWORD,supersonicads,屏蔽广告 +- DOMAIN-KEYWORD,tracking,屏蔽广告 +- DOMAIN-KEYWORD,uedas,屏蔽广告 +- DOMAIN-KEYWORD,umeng,屏蔽广告 +- DOMAIN-KEYWORD,usage,屏蔽广告 +- DOMAIN-KEYWORD,wlmonitor,屏蔽广告 +- DOMAIN-KEYWORD,zjtoolbar,屏蔽广告 +# › Baidu +- DOMAIN,a.baidu.com,屏蔽广告 +- DOMAIN,adm.baidu.com,屏蔽广告 +- DOMAIN,als.baidu.com,屏蔽广告 +- DOMAIN,api.youqian.baidu.com,屏蔽广告 +- DOMAIN,as.baidu.com,屏蔽广告 +- DOMAIN,ashifen.com,屏蔽广告 +- DOMAIN,baidustatic.com,屏蔽广告 +- DOMAIN,baidutv.baidu.com,屏蔽广告 +- DOMAIN,baikebcs.bdimg.com,屏蔽广告 +- DOMAIN,bar.baidu.com,屏蔽广告 +- DOMAIN,bdimg.share.baidu.com,屏蔽广告 +- DOMAIN,boscdn.bpc.baidu.com,屏蔽广告 +- DOMAIN,c.baidu.com,屏蔽广告 +- DOMAIN,cbjs.baidu.com,屏蔽广告 +- DOMAIN,cjhq.baidu.com,屏蔽广告 +- DOMAIN,cpro.baidu.com,屏蔽广告 +- DOMAIN,cpro.tieba.baidu.com,屏蔽广告 +- DOMAIN,cpro.zhidao.baidu.com,屏蔽广告 +- DOMAIN,dcps.nuomi.com,屏蔽广告 +- DOMAIN,drmcmm.baidu.com,屏蔽广告 +- DOMAIN,e.baidu.com,屏蔽广告 +- DOMAIN,eiv.baidu.com,屏蔽广告 +- DOMAIN,feed.baidu.com,屏蔽广告 +- DOMAIN,focusbaiduafp.allyes.com,屏蔽广告 +- DOMAIN,hc.baidu.com,屏蔽广告 +- DOMAIN,hm.baidu.com,屏蔽广告 +- DOMAIN,hmma.baidu.com,屏蔽广告 +- DOMAIN,hpd.baidu.com,屏蔽广告 +- DOMAIN,idm-su.baidu.com,屏蔽广告 +- DOMAIN,imageplus.baidu.com,屏蔽广告 +- DOMAIN,itsdata.map.baidu.com,屏蔽广告 +- DOMAIN,libs.baidu.com,屏蔽广告 +- DOMAIN,log.nuomi.com,屏蔽广告 +- DOMAIN,log.waimai.baidu.com,屏蔽广告 +- DOMAIN,ma.baidu.com,屏蔽广告 +- DOMAIN,mobads-logs.baidu.com,屏蔽广告 +- DOMAIN,mobads.baidu.com,屏蔽广告 +- DOMAIN,nsclick.baidu.com,屏蔽广告 +- DOMAIN,qchannel01.cn,屏蔽广告 +- DOMAIN,rj.baidu.com,屏蔽广告 +- DOMAIN,shifen.com,屏蔽广告 +- DOMAIN,spcode.baidu.com,屏蔽广告 +- DOMAIN,static.map.bdimg.com,屏蔽广告 +- DOMAIN,static.su.baidu.com,屏蔽广告 +- DOMAIN,tk.baidu.com,屏蔽广告 +- DOMAIN,tuisong.baidu.com,屏蔽广告 +- DOMAIN,ucstat.baidu.com,屏蔽广告 +- DOMAIN,ufosdk.baidu.com,屏蔽广告 +- DOMAIN,ulog.imap.baidu.com,屏蔽广告 +- DOMAIN,union.baidu.com,屏蔽广告 +- DOMAIN,utility.baidu.com,屏蔽广告 +- DOMAIN,utk.baidu.com,屏蔽广告 +- DOMAIN,wangmeng.baidu.com,屏蔽广告 +- DOMAIN,wm.baidu.com,屏蔽广告 +- DOMAIN,wn.pos.baidu.com,屏蔽广告 +- DOMAIN,zhanzhang.baidu.com,屏蔽广告 +- DOMAIN,znsv.baidu.com,屏蔽广告 +- DOMAIN,zz.bdstatic.com,屏蔽广告 +# › Ali +- DOMAIN,acjs.aliyun.com,屏蔽广告 +- DOMAIN,adash-c.ut.taobao.com,屏蔽广告 +- DOMAIN,adash.m.taobao.com,屏蔽广告 +- DOMAIN,adashbc.m.taobao.com,屏蔽广告 +- DOMAIN,adashx.m.taobao.com,屏蔽广告 +- DOMAIN,afp.alicdn.com,屏蔽广告 +- DOMAIN,alipaylog.com,屏蔽广告 +- DOMAIN,amdc.alipay.com,屏蔽广告 +- DOMAIN,amdc.m.taobao.com,屏蔽广告 +- DOMAIN,apoll.m.taobao.com,屏蔽广告 +- DOMAIN,appdownload.alicdn.com,屏蔽广告 +- DOMAIN,atanx.alicdn.com,屏蔽广告 +- DOMAIN,dorangesource.alicdn.com,屏蔽广告 +- DOMAIN,hydra.alibaba.com,屏蔽广告 +- DOMAIN,ifs.tanx.com,屏蔽广告 +- DOMAIN,m-adash.m.taobao.com,屏蔽广告 +- DOMAIN,m.simaba.taobao.com,屏蔽广告 +- DOMAIN,nbsdk-baichuan.alicdn.com,屏蔽广告 +- DOMAIN,nbsdk-baichuan.taobao.com,屏蔽广告 +- DOMAIN,pics.taobaocdn.com,屏蔽广告 +- DOMAIN,show.re.taobao.com,屏蔽广告 +- DOMAIN,strip.taobaocdn.com,屏蔽广告 +- DOMAIN,tns.simba.taobao.com,屏蔽广告 +- DOMAIN,userimg.qunar.com,屏蔽广告 +- DOMAIN,yiliao.hupan.com,屏蔽广告 +# › sina +- DOMAIN,ad.sina.com.cn,屏蔽广告 +- DOMAIN,adm.leju.sina.com.cn,屏蔽广告 +- DOMAIN,atm.sina.com,屏蔽广告 +- DOMAIN,beacon.sina.com.cn,屏蔽广告 +- DOMAIN,dcads.sina.com.cn,屏蔽广告 +- DOMAIN,dp.im.weibo.cn,屏蔽广告 +- DOMAIN,imrworldwide.com,屏蔽广告 +- DOMAIN,log.weico.cc,屏蔽广告 +- DOMAIN,miaozhen.com,屏蔽广告 +- DOMAIN,sax.sina.cn,屏蔽广告 +- DOMAIN,sax.sina.com.cn,屏蔽广告 +- DOMAIN,tjs.sjs.sinajs.cn,屏蔽广告 +- DOMAIN,wax.weibo.com,屏蔽广告 +# › QQ +- DOMAIN,act.qq.com,屏蔽广告 +- DOMAIN,adsfile.qq.com,屏蔽广告 +- DOMAIN,beacon.qq.com,屏蔽广告 +- DOMAIN,btrace.qq.com,屏蔽广告 +- DOMAIN,bugly.qq.com,屏蔽广告 +- DOMAIN,e.qq.com,屏蔽广告 +- DOMAIN,gdt.qq.com,屏蔽广告 +- DOMAIN,ltsdl.qq.com,屏蔽广告 +- DOMAIN,monitor.uu.qq.com,屏蔽广告 +- DOMAIN,mtrace.qq.com,屏蔽广告 +- DOMAIN,pgdt.gtimg.cn,屏蔽广告 +- DOMAIN,pingjs.qq.com,屏蔽广告 +- DOMAIN,pingma.qq.com,屏蔽广告 +- DOMAIN,pingtcss.qq.com,屏蔽广告 +- DOMAIN,report.qq.com,屏蔽广告 +- DOMAIN,routertips.video.qq.com,屏蔽广告 +- DOMAIN,tajs.qq.com,屏蔽广告 +- DOMAIN,tcss.qq.com,屏蔽广告 +- DOMAIN,up-hl.3g.qq.com,屏蔽广告 +# › 360 +- DOMAIN,3600.com,屏蔽广告 +- DOMAIN,adapi.shouji.360.cn,屏蔽广告 +- DOMAIN,dev.tg.wan.360.cn,屏蔽广告 +- DOMAIN,huodong.ios.shouji.360.cn,屏蔽广告 +- DOMAIN,kuaikan.netmon.360safe.com,屏蔽广告 +- DOMAIN,leak.360.cn,屏蔽广告 +- DOMAIN,openbox.mobilem.360.cn,屏蔽广告 +- DOMAIN,pub.se.360.cn,屏蔽广告 +- DOMAIN,soft.data.weather.360.cn,屏蔽广告 +- DOMAIN,stat.360safe.com,屏蔽广告 +- DOMAIN,stat.m.360.cn,屏蔽广告 +- DOMAIN,update.360safe.com,屏蔽广告 +# › 163 +- DOMAIN,adgeo.163.com,屏蔽广告 +- DOMAIN,bobo.163.com,屏蔽广告 +- DOMAIN,fa.163.com,屏蔽广告 +- DOMAIN,g.163.com,屏蔽广告 +- DOMAIN,g1.163.com,屏蔽广告 +- DOMAIN,gb.corp.163.com,屏蔽广告 +- DOMAIN,haitaoad.nosdn.127.net,屏蔽广告 +- DOMAIN,img1.126.net,屏蔽广告 +- DOMAIN,oadz.com,屏蔽广告 +- DOMAIN,oimagea2.ydstatic.com,屏蔽广告 +- DOMAIN,pagechoice.net,屏蔽广告 +- DOMAIN,prom.gome.com.cn,屏蔽广告 +- DOMAIN,rlogs.youdao.com,屏蔽广告 +- DOMAIN,static.flv.uuzuonline.com,屏蔽广告 +- DOMAIN,wanproxy.127.net,屏蔽广告 + +# ›AD Block +- DOMAIN,10up.com,屏蔽广告 +- DOMAIN,111cn.net,屏蔽广告 +- DOMAIN,114la.com,屏蔽广告 +- DOMAIN,123.sogou.com,屏蔽广告 +- DOMAIN,37wan.cn,屏蔽广告 +- DOMAIN,51.la,屏蔽广告 +- DOMAIN,513hch.com,屏蔽广告 +- DOMAIN,51yes.com,屏蔽广告 +- DOMAIN,70e.com,屏蔽广告 +- DOMAIN,818mov.com,屏蔽广告 +- DOMAIN,86.cc,屏蔽广告 +- DOMAIN,9377.cn,屏蔽广告 +- DOMAIN,9377s.com,屏蔽广告 +- DOMAIN,99click.com,屏蔽广告 +- DOMAIN,a.applovin.com,屏蔽广告 +- DOMAIN,a.visualrevenue.com,屏蔽广告 +- DOMAIN,a1.itc.cn,屏蔽广告 +- DOMAIN,acs86.com,屏蔽广告 +- DOMAIN,ad.12306.cn,屏蔽广告 +- DOMAIN,ad.3.cn,屏蔽广告 +- DOMAIN,ad.360yield.com,屏蔽广告 +- DOMAIN,ad.95306.cn,屏蔽广告 +- DOMAIN,ad.cctv.com,屏蔽广告 +- DOMAIN,ad.flipboard.com,屏蔽广告 +- DOMAIN,ad.mi.com,屏蔽广告 +- DOMAIN,ad.thepaper.cn,屏蔽广告 +- DOMAIN,ad.unimhk.com,屏蔽广告 +- DOMAIN,ad.xiaomi.com,屏蔽广告 +- DOMAIN,ad.yieldlab.net,屏蔽广告 +- DOMAIN,ad.zanox.com,屏蔽广告 +- DOMAIN,ad1.xiaomi.com,屏蔽广告 +- DOMAIN,ad8.adfarm1.adition.com,屏蔽广告 +- DOMAIN,adadvisor.net,屏蔽广告 +- DOMAIN,adap.tv,屏蔽广告 +- DOMAIN,adbxb.com,屏蔽广告 +- DOMAIN,adchina.com,屏蔽广告 +- DOMAIN,adcolony.com,屏蔽广告 +- DOMAIN,adcome.cn,屏蔽广告 +- DOMAIN,ader.mobi,屏蔽广告 +- DOMAIN,adform.net,屏蔽广告 +- DOMAIN,adfuture.cn,屏蔽广告 +- DOMAIN,adinfuse.com,屏蔽广告 +- DOMAIN,adjust.com,屏蔽广告 +- DOMAIN,adjust.io,屏蔽广告 +- DOMAIN,adlive.cn,屏蔽广告 +- DOMAIN,adm.easou.com,屏蔽广告 +- DOMAIN,admin5.com,屏蔽广告 +- DOMAIN,admob.com,屏蔽广告 +- DOMAIN,admon.cn,屏蔽广告 +- DOMAIN,adnxs.com,屏蔽广告 +- DOMAIN,adpolestar.net,屏蔽广告 +- DOMAIN,adquan.com,屏蔽广告 +- DOMAIN,ads.feedly.com,屏蔽广告 +- DOMAIN,ads.genieessp.com,屏蔽广告 +- DOMAIN,ads.mobclix.com,屏蔽广告 +- DOMAIN,ads.newtentionassets.net,屏蔽广告 +- DOMAIN,ads.nexage.com,屏蔽广告 +- DOMAIN,ads.stickyadstv.com,屏蔽广告 +- DOMAIN,ads.yahoo.com,屏蔽广告 +- DOMAIN,adsame.com,屏蔽广告 +- DOMAIN,adse.ximalaya.com,屏蔽广告 +- DOMAIN,adserver.snapads.com,屏蔽广告 +- DOMAIN,adsp.xunlei.com,屏蔽广告 +- DOMAIN,adsunflower.com,屏蔽广告 +- DOMAIN,adsunion.com,屏蔽广告 +- DOMAIN,adtrk.me,屏蔽广告 +- DOMAIN,adups.com,屏蔽广告 +- DOMAIN,aduu.cn,屏蔽广告 +- DOMAIN,advertising.com,屏蔽广告 +- DOMAIN,adview.cn,屏蔽广告 +- DOMAIN,advmob.cn,屏蔽广告 +- DOMAIN,adwhirl.com,屏蔽广告 +- DOMAIN,adwo.com,屏蔽广告 +- DOMAIN,adx.tanx.com,屏蔽广告 +- DOMAIN,adxmi.com,屏蔽广告 +- DOMAIN,adzerk.net,屏蔽广告 +- DOMAIN,ajapk.com,屏蔽广告 +- DOMAIN,ak.sascdn.com,屏蔽广告 +- DOMAIN,allyes.cn,屏蔽广告 +- DOMAIN,allyes.com,屏蔽广告 +- DOMAIN,amazon-adsystem.com,屏蔽广告 +- DOMAIN,analytics.query.yahoo.com,屏蔽广告 +- DOMAIN,angsrvr.com,屏蔽广告 +- DOMAIN,anquan.org,屏蔽广告 +- DOMAIN,anysdk.com,屏蔽广告 +- DOMAIN,aoodoo.feng.com,屏蔽广告 +- DOMAIN,api.branch.io,屏蔽广告 +- DOMAIN,api.mobula.sdk.duapps.com,屏蔽广告 +- DOMAIN,api.similarweb.com,屏蔽广告 +- DOMAIN,api.talkingdata.com,屏蔽广告 +- DOMAIN,api.userstyles.org,屏蔽广告 +- DOMAIN,app-measurement.com,屏蔽广告 +- DOMAIN,appadhoc.com,屏蔽广告 +- DOMAIN,appads.com,屏蔽广告 +- DOMAIN,appboy.com,屏蔽广告 +- DOMAIN,applifier.com,屏蔽广告 +- DOMAIN,applovin.com,屏蔽广告 +- DOMAIN,appsflyer.com,屏蔽广告 +- DOMAIN,atdmt.com,屏蔽广告 +- DOMAIN,audience.network,屏蔽广告 +- DOMAIN,baifendian.com,屏蔽广告 +- DOMAIN,bam.nr-data.net,屏蔽广告 +- DOMAIN,bat.bing.com,屏蔽广告 +- DOMAIN,baycode.cn,屏蔽广告 +- DOMAIN,beacon.krxd.net,屏蔽广告 +- DOMAIN,beacon.tingyun.com,屏蔽广告 +- DOMAIN,behe.com,屏蔽广告 +- DOMAIN,biddingx.com,屏蔽广告 +- DOMAIN,bsdev.cn,屏蔽广告 +- DOMAIN,btyou.com,屏蔽广告 +- DOMAIN,buysellads.com,屏蔽广告 +- DOMAIN,c.metrigo.com,屏蔽广告 +- DOMAIN,c0563.com,屏蔽广告 +- DOMAIN,cchfjz.com,屏蔽广告 +- DOMAIN,cdn.jiuzhilan.com,屏蔽广告 +- DOMAIN,chance-ad.com,屏蔽广告 +- DOMAIN,chartbeat.com,屏蔽广告 +- DOMAIN,chartboost.com,屏蔽广告 +- DOMAIN,chmae.com,屏蔽广告 +- DOMAIN,clicktracks.com,屏蔽广告 +- DOMAIN,clickzs.com,屏蔽广告 +- DOMAIN,cloudmobi.net,屏蔽广告 +- DOMAIN,cmcore.com,屏蔽广告 +- DOMAIN,cnzz.com,屏蔽广告 +- DOMAIN,cnzzlink.com,屏蔽广告 +- DOMAIN,collector.githubapp.com,屏蔽广告 +- DOMAIN,combine.urbanairship.com,屏蔽广告 +- DOMAIN,config.ioam.de,屏蔽广告 +- DOMAIN,config2.mparticle.com,屏蔽广告 +- DOMAIN,coremetrics.com,屏蔽广告 +- DOMAIN,cps.360buy.com,屏蔽广告 +- DOMAIN,crunchyroll.com,屏蔽广告 +- DOMAIN,csi.gstatic.com,屏蔽广告 +- DOMAIN,customer-security.online,屏蔽广告 +- DOMAIN,cxaerp.com,屏蔽广告 +- DOMAIN,czxiangyue.com,屏蔽广告 +- DOMAIN,d.applovin.com,屏蔽广告 +- DOMAIN,d.ligatus.com,屏蔽广告 +- DOMAIN,ddapp.cn,屏蔽广告 +- DOMAIN,de.ioam.de,屏蔽广告 +- DOMAIN,dianru.com,屏蔽广告 +- DOMAIN,dis.crieto.com,屏蔽广告 +- DOMAIN,disqusads.com,屏蔽广告 +- DOMAIN,doubleclick.net,屏蔽广告 +- DOMAIN,doubleverify.com,屏蔽广告 +- DOMAIN,drdwy.com,屏蔽广告 +- DOMAIN,dsp.youdao.com,屏蔽广告 +- DOMAIN,duanat.com,屏蔽广告 +- DOMAIN,duapp.com,屏蔽广告 +- DOMAIN,e.nexac.com,屏蔽广告 +- DOMAIN,e701.net,屏蔽广告 +- DOMAIN,edigitalsurvey.com,屏蔽广告 +- DOMAIN,emarbox.com,屏蔽广告 +- DOMAIN,exp.17wo.cn,屏蔽广告 +- DOMAIN,fancyapi.com,屏蔽广告 +- DOMAIN,farm.plista.com,屏蔽广告 +- DOMAIN,fastapi.net,屏蔽广告 +- DOMAIN,fastclick.net,屏蔽广告 +- DOMAIN,fastly.bench.cedexis.com,屏蔽广告 +- DOMAIN,fd7c.com,屏蔽广告 +- DOMAIN,fengbuy.com,屏蔽广告 +- DOMAIN,ffychb.com,屏蔽广告 +- DOMAIN,fjzdmy.com,屏蔽广告 +- DOMAIN,flashtalking.com,屏蔽广告 +- DOMAIN,flurry.com,屏蔽广告 +- DOMAIN,fqtra.com,屏蔽广告 +- DOMAIN,fzxrjx.com,屏蔽广告 +- DOMAIN,gdsc168.com,屏蔽广告 +- DOMAIN,gg1028.com,屏蔽广告 +- DOMAIN,glispa.com,屏蔽广告 +- DOMAIN,go-mpulse,屏蔽广告 +- DOMAIN,growingio.com,屏蔽广告 +- DOMAIN,guohead.com,屏蔽广告 +- DOMAIN,guomob.com,屏蔽广告 +- DOMAIN,haoghost.com,屏蔽广告 +- DOMAIN,haohaowan8.com,屏蔽广告 +- DOMAIN,he2d.com,屏蔽广告 +- DOMAIN,hnxxjn.com,屏蔽广告 +- DOMAIN,hosting.miarroba.info,屏蔽广告 +- DOMAIN,hxspc.com,屏蔽广告 +- DOMAIN,iadsdk.apple.com,屏蔽广告 +- DOMAIN,ih.adscale.de,屏蔽广告 +- DOMAIN,image.gentags.com,屏蔽广告 +- DOMAIN,immob.cn,屏蔽广告 +- DOMAIN,inmobi.com,屏蔽广告 +- DOMAIN,inmobicdn.net,屏蔽广告 +- DOMAIN,instabug.com,屏蔽广告 +- DOMAIN,intely.cn,屏蔽广告 +- DOMAIN,iperceptions.com,屏蔽广告 +- DOMAIN,ipinyou.com,屏蔽广告 +- DOMAIN,irs01.com,屏蔽广告 +- DOMAIN,irs01.net,屏蔽广告 +- DOMAIN,irs09.com,屏蔽广告 +- DOMAIN,istreamsche.com,屏蔽广告 +- DOMAIN,jbcbuy.com,屏蔽广告 +- DOMAIN,jdcbuy.com,屏蔽广告 +- DOMAIN,jisucn.com,屏蔽广告 +- DOMAIN,jmgehn.cn,屏蔽广告 +- DOMAIN,js-agent.newrelic.com,屏蔽广告 +- DOMAIN,jusha.com,屏蔽广告 +- DOMAIN,jzm81.com,屏蔽广告 +- DOMAIN,kaquansc.com,屏蔽广告 +- DOMAIN,kejet.net,屏蔽广告 +- DOMAIN,kmd365.com,屏蔽广告 +- DOMAIN,krux.net,屏蔽广告 +- DOMAIN,linkeye.ximalaya.com,屏蔽广告 +- DOMAIN,lnk8z.com,屏蔽广告 +- DOMAIN,localytics.com,屏蔽广告 +- DOMAIN,location.ximalaya.com,屏蔽广告 +- DOMAIN,log.outbrain.com,屏蔽广告 +- DOMAIN,log.umsns.com,屏蔽广告 +- DOMAIN,logs.dashlane.com,屏蔽广告 +- DOMAIN,lotuseed.com,屏蔽广告 +- DOMAIN,lufax.com,屏蔽广告 +- DOMAIN,madmini.com,屏蔽广告 +- DOMAIN,mads.amazon.com,屏蔽广告 +- DOMAIN,mathtag.com,屏蔽广告 +- DOMAIN,mediav.com,屏蔽广告 +- DOMAIN,megajoy.com,屏蔽广告 +- DOMAIN,miidi.net,屏蔽广告 +- DOMAIN,mixpanel.com,屏蔽广告 +- DOMAIN,mng-ads.com,屏蔽广告 +- DOMAIN,mnxtu.com,屏蔽广告 +- DOMAIN,moatads.com,屏蔽广告 +- DOMAIN,mob.com,屏蔽广告 +- DOMAIN,mobclix.com,屏蔽广告 +- DOMAIN,mobfox.com,屏蔽广告 +- DOMAIN,mobileads.msn.com,屏蔽广告 +- DOMAIN,mobileapptracking.com,屏蔽广告 +- DOMAIN,mobisage.cn,屏蔽广告 +- DOMAIN,mobtop1.com,屏蔽广告 +- DOMAIN,mopub.com,屏蔽广告 +- DOMAIN,mxpnl.com,屏蔽广告 +- DOMAIN,myhug.cn,屏蔽广告 +- DOMAIN,n.cosbot.cn,屏蔽广告 +- DOMAIN,nchte.com,屏蔽广告 +- DOMAIN,networkbench.com,屏蔽广告 +- DOMAIN,newrelic.com,屏蔽广告 +- DOMAIN,ntalker.com,屏蔽广告 +- DOMAIN,ntjacb.com,屏蔽广告 +- DOMAIN,ntpddq.com,屏蔽广告 +- DOMAIN,nylalobghyhirgh.com,屏蔽广告 +- DOMAIN,o2omobi.com,屏蔽广告 +- DOMAIN,oneapm.com,屏蔽广告 +- DOMAIN,optaim.com,屏蔽广告 +- DOMAIN,optimix.asia,屏蔽广告 +- DOMAIN,optimizely.com,屏蔽广告 +- DOMAIN,overture.com,屏蔽广告 +- DOMAIN,page.amap.com,屏蔽广告 +- DOMAIN,pb.sogou.com,屏蔽广告 +- DOMAIN,picture.duokan.com,屏蔽广告 +- DOMAIN,pingdom.net,屏蔽广告 +- DOMAIN,pingshetrip.com,屏蔽广告 +- DOMAIN,pixel.rubiconproject.com,屏蔽广告 +- DOMAIN,pixel.wp.com,屏蔽广告 +- DOMAIN,ppjia55.com,屏蔽广告 +- DOMAIN,probes.cedexis.com,屏蔽广告 +- DOMAIN,prophet.heise.de,屏蔽广告 +- DOMAIN,publicidad.net,屏蔽广告 +- DOMAIN,publicidad.tv,屏蔽广告 +- DOMAIN,pubnub.com,屏蔽广告 +- DOMAIN,push.wandoujia.com,屏蔽广告 +- DOMAIN,qcl777.com,屏蔽广告 +- DOMAIN,qhuade.com,屏蔽广告 +- DOMAIN,qiyou.com,屏蔽广告 +- DOMAIN,qtmojo.com,屏蔽广告 +- DOMAIN,quantcount.com,屏蔽广告 +- DOMAIN,quantserve.com,屏蔽广告 +- DOMAIN,qxxys.com,屏蔽广告 +- DOMAIN,radar.cedexis.com,屏蔽广告 +- DOMAIN,reachmax.cn,屏蔽广告 +- DOMAIN,realtime.monitor.ppweb.com.cn,屏蔽广告 +- DOMAIN,resetgey.com,屏蔽广告 +- DOMAIN,responsys.net,屏蔽广告 +- DOMAIN,revsci.net,屏蔽广告 +- DOMAIN,rlcdn.com,屏蔽广告 +- DOMAIN,router.bittorrent.com,屏蔽广告 +- DOMAIN,rt.applovin.com,屏蔽广告 +- DOMAIN,rtb.eanalyzer.de,屏蔽广告 +- DOMAIN,rtb.metrigo.com,屏蔽广告 +- DOMAIN,rts.mobula.sdk.duapps.com,屏蔽广告 +- DOMAIN,sanya1.com,屏蔽广告 +- DOMAIN,scorecardresearch.com,屏蔽广告 +- DOMAIN,serving-sys.com,屏蔽广告 +- DOMAIN,shentus.com,屏蔽广告 +- DOMAIN,shuiguo.com,屏蔽广告 +- DOMAIN,simaba.taobao.com,屏蔽广告 +- DOMAIN,sitemeter.com,屏蔽广告 +- DOMAIN,sitescout.com,屏蔽广告 +- DOMAIN,smartadserver.com,屏蔽广告 +- DOMAIN,smartmad.com,屏蔽广告 +- DOMAIN,somecoding.com,屏蔽广告 +- DOMAIN,spade.twitch.tv,屏蔽广告 +- DOMAIN,sponsorpay.com,屏蔽广告 +- DOMAIN,ssp.kssws.ks-cdn.com,屏蔽广告 +- DOMAIN,stat.m.jd.com,屏蔽广告 +- DOMAIN,static-xl9-ssl.xunlei.com,屏蔽广告 +- DOMAIN,static.plista.com,屏蔽广告 +- DOMAIN,stats.chinaz.com,屏蔽广告 +- DOMAIN,stats.developingperspective.com,屏蔽广告 +- DOMAIN,stats.jpush.cn,屏蔽广告 +- DOMAIN,stats.magicwindow.cn,屏蔽广告 +- DOMAIN,sugar.zhihu.com,屏蔽广告 +- DOMAIN,switchadhub.com,屏蔽广告 +- DOMAIN,sycbbs.com,屏蔽广告 +- DOMAIN,synacast.com,屏蔽广告 +- DOMAIN,sysdig.com,屏蔽广告 +- DOMAIN,szddst.com,屏蔽广告 +- DOMAIN,t.appsflyer.com,屏蔽广告 +- DOMAIN,t1.visualrevenue.com,屏蔽广告 +- DOMAIN,tag.yoc-adserver.com,屏蔽广告 +- DOMAIN,tapjoyads.com,屏蔽广告 +- DOMAIN,tedagz.com,屏蔽广告 +- DOMAIN,th7.cn,屏蔽广告 +- DOMAIN,tiangoutai.com,屏蔽广告 +- DOMAIN,tiqcdn.com,屏蔽广告 +- DOMAIN,tjlog.easou.com,屏蔽广告 +- DOMAIN,tjlog.ps.easou.com,屏蔽广告 +- DOMAIN,tongbu.com,屏蔽广告 +- DOMAIN,tracker.yhd.com,屏蔽广告 +- DOMAIN,trafficmp.com,屏蔽广告 +- DOMAIN,twcczhu.com,屏蔽广告 +- DOMAIN,uerzyr.cn,屏蔽广告 +- DOMAIN,ugvip.com,屏蔽广告 +- DOMAIN,ukeiae.com,屏蔽广告 +- DOMAIN,umtrack.com,屏蔽广告 +- DOMAIN,unimhk.com,屏蔽广告 +- DOMAIN,union.youdao.com,屏蔽广告 +- DOMAIN,unlitui.com,屏蔽广告 +- DOMAIN,uri6.com,屏蔽广告 +- DOMAIN,ushaqi.com,屏蔽广告 +- DOMAIN,uyunad.com,屏蔽广告 +- DOMAIN,vamaker.com,屏蔽广告 +- DOMAIN,video.plista.com,屏蔽广告 +- DOMAIN,vpon.com,屏蔽广告 +- DOMAIN,wanfeng1.com,屏蔽广告 +- DOMAIN,waps.cn,屏蔽广告 +- DOMAIN,whpxy.com,屏蔽广告 +- DOMAIN,whzhi.com,屏蔽广告 +- DOMAIN,wiyun.com,屏蔽广告 +- DOMAIN,wooboo.com.cn,屏蔽广告 +- DOMAIN,wqmobile.com,屏蔽广告 +- DOMAIN,wrating.com,屏蔽广告 +- DOMAIN,x.jd.com,屏蔽广告 +- DOMAIN,x.ligatus.com,屏蔽广告 +- DOMAIN,xdbwc.com,屏蔽广告 +- DOMAIN,xdcs-collector.ximalaya.com,屏蔽广告 +- DOMAIN,xiaozhen.com,屏蔽广告 +- DOMAIN,xibao100.com,屏蔽广告 +- DOMAIN,xmpush.xiaomi.com,屏蔽广告 +- DOMAIN,xmrts.com,屏蔽广告 +- DOMAIN,xy.com,屏蔽广告 +- DOMAIN,xyrkl.com,屏蔽广告 +- DOMAIN,yandui.com,屏蔽广告 +- DOMAIN,yes1.feng.com,屏蔽广告 +- DOMAIN,yigao.com,屏蔽广告 +- DOMAIN,yigyx.com,屏蔽广告 +- DOMAIN,yiqifa.com,屏蔽广告 +- DOMAIN,yooli.com,屏蔽广告 +- DOMAIN,youle55.com,屏蔽广告 +- DOMAIN,youmi.net,屏蔽广告 +- DOMAIN,yrxgny.com,屏蔽广告 +- DOMAIN,yrxmr.com,屏蔽广告 +- DOMAIN,ysjwj.com,屏蔽广告 +- DOMAIN,yunjiasu.com,屏蔽广告 +- DOMAIN,zantainet.com,屏蔽广告 +- DOMAIN,zhihu-web-analytics.zhihu.com,屏蔽广告 +- DOMAIN,zhiziyun.com,屏蔽广告 +- DOMAIN,zhstatic.zhihu.com,屏蔽广告 +- DOMAIN,zhuanfakong.com,屏蔽广告 +- DOMAIN,zjuwjdc.com,屏蔽广告 +- DOMAIN,zzsx8.com,屏蔽广告 +- DOMAIN,szkdst.com,屏蔽广告 +- DOMAIN,cwpush.com,屏蔽广告 +- DOMAIN,wvver.com,屏蔽广告 +- DOMAIN,vq6nsu.cn,屏蔽广告 +- DOMAIN,ourlj.com,屏蔽广告 +- DOMAIN,zgjkv.com,屏蔽广告 +- DOMAIN,v02u9.cn,屏蔽广告 +- DOMAIN,xiongdong.com,屏蔽广告 +- DOMAIN,519397.com,屏蔽广告 +- DOMAIN,twh5.com,屏蔽广告 + + +# ›iqiyi +- DOMAIN,a.ckm.iqiyi.com,屏蔽广告 +- DOMAIN,ad.m.iqiyi.com,屏蔽广告 +- DOMAIN,afp.iqiyi.com,屏蔽广告 +- DOMAIN,c.uaa.iqiyi.com,屏蔽广告 +- DOMAIN,cloudpush.iqiyi.com,屏蔽广告 +- DOMAIN,cm.passport.iqiyi.com,屏蔽广告 +- DOMAIN,cupid.iqiyi.com,屏蔽广告 +- DOMAIN,emoticon.sns.iqiyi.com,屏蔽广告 +- DOMAIN,gamecenter.iqiyi.com,屏蔽广告 +- DOMAIN,hotchat-im.iqiyi.com,屏蔽广告 +- DOMAIN,ifacelog.iqiyi.com,屏蔽广告 +- DOMAIN,mbdlog.iqiyi.com,屏蔽广告 +- DOMAIN,msg.71.am,屏蔽广告 +- DOMAIN,msg.video.qiyi.com,屏蔽广告 +- DOMAIN,msg2.video.qiyi.com,屏蔽广告 +- DOMAIN,policy.video.iqiyi.com,屏蔽广告 +- DOMAIN,yuedu.iqiyi.com,屏蔽广告 +- IP-CIDR,101.227.200.0/24,屏蔽广告 +- IP-CIDR,101.227.200.11/32,屏蔽广告 +- IP-CIDR,101.227.200.28/32,屏蔽广告 +- IP-CIDR,101.227.97.240/32,屏蔽广告 +- IP-CIDR,124.192.153.42/32,屏蔽广告 + +# ›Hunan TV +- DOMAIN,click.hunantv.com,屏蔽广告 +- DOMAIN,da.hunantv.com,屏蔽广告 +- DOMAIN,da.mgtv.com,屏蔽广告 +- DOMAIN,log.hunantv.com,屏蔽广告 +- DOMAIN,log.v2.hunantv.com,屏蔽广告 +- DOMAIN,res.hunantv.com,屏蔽广告 +- DOMAIN,v2.log.hunantv.com,屏蔽广告 + +# ›Youku +- DOMAIN,actives.youku.com,屏蔽广告 +- DOMAIN,ad.api.3g.youku.com,屏蔽广告 +- DOMAIN,ad.api.mobile.youku.com,屏蔽广告 +- DOMAIN,ad.mobile.youku.com,屏蔽广告 +- DOMAIN,a-dxk.play.api.3g.youku.com,屏蔽广告 +- DOMAIN,b.smartvideo.youku.com,屏蔽广告 +- DOMAIN,c.yes.youku.com,屏蔽广告 +- DOMAIN,das.api.youku.com,屏蔽广告 +- DOMAIN,das.mobile.youku.com,屏蔽广告 +- DOMAIN,dev-push.m.youku.com,屏蔽广告 +- DOMAIN,dl.g.youku.com,屏蔽广告 +- DOMAIN,dmapp.youku.com,屏蔽广告 +- DOMAIN,e.stat.ykimg.com,屏蔽广告 +- DOMAIN,gamex.mobile.youku.com,屏蔽广告 +- DOMAIN,hudong.pl.youku.com,屏蔽广告 +- DOMAIN,huodong.pl.youku.com,屏蔽广告 +- DOMAIN,huodong.vip.youku.com,屏蔽广告 +- DOMAIN,hz.youku.com,屏蔽广告 +- DOMAIN,iyes.youku.com,屏蔽广告 +- DOMAIN,l.ykimg.com,屏蔽广告 +- DOMAIN,lstat.youku.com,屏蔽广告 +- DOMAIN,mobilemsg.youku.com,屏蔽广告 +- DOMAIN,msg.youku.com,屏蔽广告 +- DOMAIN,myes.youku.com,屏蔽广告 +- DOMAIN,p.l.youku.com,屏蔽广告 +- DOMAIN,passport-log.youku.com,屏蔽广告 +- DOMAIN,p-log.ykimg.com,屏蔽广告 +- DOMAIN,push.m.youku.com,屏蔽广告 +- DOMAIN,r.l.youku.com,屏蔽广告 +- DOMAIN,s.p.youku.com,屏蔽广告 +- DOMAIN,sdk.m.youku.com,屏蔽广告 +- DOMAIN,stat.youku.com,屏蔽广告 +- DOMAIN,store.tv.api.3g.youku.com,屏蔽广告 +- DOMAIN,store.xl.api.3g.youku.com,屏蔽广告 +- DOMAIN,tdrec.youku.com,屏蔽广告 +- DOMAIN,test.ott.youku.com,屏蔽广告 +- DOMAIN,v.l.youku.com,屏蔽广告 +- DOMAIN,val.api.youku.com,屏蔽广告 +- DOMAIN,wan.youku.com,屏蔽广告 +- DOMAIN,ykatr.youku.com,屏蔽广告 +- DOMAIN,ykrec.youku.com,屏蔽广告 +- IP-CIDR,117.177.248.17/32,屏蔽广告 +- IP-CIDR,117.177.248.41/32,屏蔽广告 +- IP-CIDR,223.87.176.139/32,屏蔽广告 +- IP-CIDR,223.87.176.176/32,屏蔽广告 +- IP-CIDR,223.87.177.180/32,屏蔽广告 +- IP-CIDR,223.87.177.182/32,屏蔽广告 +- IP-CIDR,223.87.177.184/32,屏蔽广告 +- IP-CIDR,223.87.177.43/32,屏蔽广告 +- IP-CIDR,223.87.177.47/32,屏蔽广告 +- IP-CIDR,223.87.177.80/32,屏蔽广告 +- IP-CIDR,223.87.182.101/32,屏蔽广告 +- IP-CIDR,223.87.182.102/32,屏蔽广告 +- IP-CIDR,223.87.182.11/32,屏蔽广告 +- IP-CIDR,223.87.182.52/32,屏蔽广告 + +# ›Letv +- DOMAIN,api.game.letvstore.com,屏蔽广告 +- DOMAIN,ark.letv.com,屏蔽广告 +- DOMAIN,dc.letv.com,屏蔽广告 +- DOMAIN,fz.letv.com,屏蔽广告 +- DOMAIN,g3.letv.com,屏蔽广告 +- DOMAIN,minisite.letv.com,屏蔽广告 +- DOMAIN,msg.m.letv.com,屏蔽广告 +- DOMAIN,n.mark.letv.com,屏蔽广告 +- DOMAIN,pro.hoye.letv.com,屏蔽广告 +- DOMAIN,pro.letv.com,屏蔽广告 +- DOMAIN,stat.letv.com,屏蔽广告 +- DOMAIN,static.app.m.letv.com,屏蔽广告 +- DOMAIN,webp2p.letv.com,屏蔽广告 + + +# ›Sohu +- DOMAIN,adnet.sohu.com,屏蔽广告 +- DOMAIN,ads.sohu.com,屏蔽广告 +- DOMAIN,aty.sohu.com,屏蔽广告 +- DOMAIN,data.vod.itc.cn,屏蔽广告 +- DOMAIN,epro.sogou.com,屏蔽广告 +- DOMAIN,go.sohu.com,屏蔽广告 +- DOMAIN,golden1.sogou.com,屏蔽广告 +- DOMAIN,imp.optaim.com,屏蔽广告 +- DOMAIN,inte.sogou.com,屏蔽广告 +- DOMAIN,inte.sogoucdn.com,屏蔽广告 +- DOMAIN,lu.sogoucdn.com,屏蔽广告 +- DOMAIN,theta.sogoucdn.com,屏蔽广告 +- DOMAIN,uranus.sogou.com,屏蔽广告 +- DOMAIN,v2.reachmax.cn,屏蔽广告 + +# ›PPTV +- DOMAIN,ads.aplus.pptv.com,屏蔽广告 +- DOMAIN,afp.pplive.com,屏蔽广告 +- DOMAIN,asimgs.pplive.cn,屏蔽广告 +- DOMAIN,de.as.pptv.com,屏蔽广告 +- DOMAIN,jp.as.pptv.com,屏蔽广告 +- DOMAIN,pp2.pptv.com,屏蔽广告 +- DOMAIN,stat.pptv.com,屏蔽广告 + +# ›Site +- DOMAIN,deliver.ifeng.com,屏蔽广告 +- DOMAIN,hxjs.tool.hexun.com,屏蔽广告 +- DOMAIN,hxsame.hexun.com,屏蔽广告 +- DOMAIN,itv.hexun.com,屏蔽广告 + +# ›Vod +- DOMAIN,ad.cmvideo.cn,屏蔽广告 +- DOMAIN,atm.cp31.ott.cibntv.net,屏蔽广告 +- DOMAIN,aty.cp45.ott.cibntv.net,屏蔽广告 +- DOMAIN,aty.sohu.com,屏蔽广告 +- DOMAIN,cpm.cm.kankan.com,屏蔽广告 +- DOMAIN,float.kankan.com,屏蔽广告 +- DOMAIN,houyi.baofeng.net,屏蔽广告 +- DOMAIN,iadctest.qwapi.com,屏蔽广告 +- DOMAIN,log.moviebox.baofeng.com,屏蔽广告 +- DOMAIN,logger.baofeng.com,屏蔽广告 + +# ›Other +- DOMAIN,ad.video.51togic.com,屏蔽广告 +- DOMAIN,ads.cdn.tvb.com,屏蔽广告 +- DOMAIN,biz5.kankan.com,屏蔽广告 +- DOMAIN,c.algovid.com,屏蔽广告 +- DOMAIN,cms.laifeng.com,屏蔽广告 +- DOMAIN,da.mmarket.com,屏蔽广告 +- DOMAIN,data.vod.itc.cn,屏蔽广告 +- DOMAIN,dotcounter.douyutv.com,屏蔽广告 +- DOMAIN,g.uusee.com,屏蔽广告 +- DOMAIN,game.pps.tv,屏蔽广告 +- DOMAIN,gcdn.2mdn.net,屏蔽广告 +- DOMAIN,gentags.net,屏蔽广告 +- DOMAIN,gg.jtertp.com,屏蔽广告 +- DOMAIN,gug.ku6cdn.com,屏蔽广告 +- DOMAIN,hp.smiler-ad.com,屏蔽广告 +- DOMAIN,kooyum.com,屏蔽广告 +- DOMAIN,ld.kuaigames.com,屏蔽广告 +- DOMAIN,logstat.t.sfht.com,屏蔽广告 +- DOMAIN,match.rtbidder.net,屏蔽广告 +- DOMAIN,mixer.cupid.ptqy.gitv.tv,屏蔽广告 +- DOMAIN,msg.c002.ottcn.com,屏蔽广告 +- DOMAIN,msga.ptqy.gitv.tv,屏蔽广告 +- DOMAIN,njwxh.com,屏蔽广告 +- DOMAIN,nl.rcd.ptqy.gitv.tv,屏蔽广告 +- DOMAIN,n-st.vip.com,屏蔽广告 +- DOMAIN,pb.bi.gitv.tv,屏蔽广告 +- DOMAIN,pop.uusee.com,屏蔽广告 +- DOMAIN,pq.stat.ku6.com,屏蔽广告 +- DOMAIN,rd.kuaigames.com,屏蔽广告 +- DOMAIN,shizen-no-megumi.com,屏蔽广告 +- DOMAIN,shrek.6.cn,屏蔽广告 +- DOMAIN,simba.6.cn,屏蔽广告 +- DOMAIN,st.vq.ku6.cn,屏蔽广告 +- DOMAIN,statcounter.com,屏蔽广告 +- DOMAIN,static.duoshuo.com,屏蔽广告 +- DOMAIN,static.g.ppstream.com,屏蔽广告 +- DOMAIN,static.ku6.com,屏蔽广告 +- DOMAIN,static8.pmadx.com,屏蔽广告 +- DOMAIN,store.ptqy.gitv.tv,屏蔽广告 +- DOMAIN,t7z.cupid.ptqy.gitv.tv,屏蔽广告 +- DOMAIN,traffic.uusee.com,屏蔽广告 +- DOMAIN,union.6.cn,屏蔽广告 +- DOMAIN,wa.gtimg.com,屏蔽广告 +- DOMAIN,bfshan.cn,屏蔽广告 +# (Domestic) +# > 愛奇藝台灣站 +- DOMAIN-SUFFIX,iqiyi.com,Domestic +- DOMAIN-SUFFIX,71.am,Domestic +# > bilibili +- DOMAIN-KEYWORD,bilibili,Domestic +- DOMAIN-SUFFIX,bilibili.com,Domestic +- DOMAIN,upos-hz-mirrorakam.akamaized.net,Domestic +- DOMAIN-SUFFIX,acgvideo.com,Domestic +- DOMAIN-SUFFIX,biliapi.com,Domestic +- DOMAIN-SUFFIX,biliapi.net,Domestic +- DOMAIN-SUFFIX,bilibili.com,Domestic +- DOMAIN-SUFFIX,bilibili.tv,Domestic +- DOMAIN-SUFFIX,hdslb.com,Domestic +# USER-AGENT,All4*,Global_media +- DOMAIN-SUFFIX,c4assets.com,Global_media +- DOMAIN-SUFFIX,channel4.com,Global_media +# > AbemaTV +# USER-AGENT,AbemaTV*,Global_media +- DOMAIN-SUFFIX,abema.io,Global_media +- DOMAIN-SUFFIX,ameba.jp,Global_media +- DOMAIN-SUFFIX,hayabusa.io,Global_media +- DOMAIN,abematv.akamaized.net,Global_media +- DOMAIN,ds-linear-abematv.akamaized.net,Global_media +- DOMAIN,ds-vod-abematv.akamaized.net,Global_media +- DOMAIN,linear-abematv.akamaized.net,Global_media +# > Amazon Prime Video +# USER-AGENT,InstantVideo.US*,美区影视 +# USER-AGENT,Prime%20Video*,美区影视 +- DOMAIN-SUFFIX,primevideo.com,美区影视 +# > Bahamut +# USER-AGENT,Anime*,动画疯 +- DOMAIN-SUFFIX,bahamut.com.tw,动画疯 +- DOMAIN-SUFFIX,gamer.com.tw,动画疯 +- DOMAIN,gamer-cds.cdn.hinet.net,动画疯 +- DOMAIN,gamer2-cds.cdn.hinet.net,动画疯 +# > BBC iPlayer +# USER-AGENT,BBCiPlayer*,Global_media +- DOMAIN-SUFFIX,bbc.co.uk,Global_media +- DOMAIN-SUFFIX,bbci.co.uk,Global_media +- DOMAIN-KEYWORD,bbcfmt,Global_media +- DOMAIN-KEYWORD,uk-live,Global_media +# > DAZN +- DOMAIN-SUFFIX,dazn.com,Global_media +# > encoreTVB +# USER-AGENT,encoreTVB*,Global_media +- DOMAIN-SUFFIX,encoretvb.com,Global_media +- DOMAIN,content.jwplatform.com,Global_media +- DOMAIN,videos-f.jwpsrv.com,Global_media +# > Fox+ & Fox Now +# USER-AGENT,FOX%20NOW*,fox+ +# USER-AGENT,FOXPlus*,fox+ +- DOMAIN-SUFFIX,dashasiafox.akamaized.net,fox+ +- DOMAIN-SUFFIX,fox.com,fox+ +- DOMAIN-SUFFIX,foxdcg.com,fox+ +- DOMAIN-SUFFIX,foxplus.com,fox+ +- DOMAIN-SUFFIX,staticasiafox.akamaized.net,fox+ +- DOMAIN-SUFFIX,theplatform.com,fox+ +- DOMAIN-SUFFIX,uplynk.com,fox+ +# > HBO Now & HBO GO +# USER-AGENT,HBO%20NOW*,美区影视 +# USER-AGENT,HBO%20GO*,美区影视 +# USER-AGENT,HBOAsia*,美区影视 +- DOMAIN-SUFFIX,hbo.com,美区影视 +- DOMAIN-SUFFIX,hbogo.com,美区影视 +- DOMAIN-SUFFIX,hboasia.com,美区影视 +- DOMAIN-SUFFIX,hbogo.com,美区影视 +- DOMAIN-SUFFIX,hbogoasia.hk,美区影视 +- DOMAIN,44wilhpljf.execute-api.ap-southeast-1.amazonaws.com,美区影视 +- DOMAIN,bcbolthboa-a.akamaihd.net,美区影视 +- DOMAIN,cf-images.ap-southeast-1.prod.boltdns.net,美区影视 +- DOMAIN,manifest.prod.boltdns.net,美区影视 +- DOMAIN,s3-ap-southeast-1.amazonaws.com,美区影视 +# > Hulu +- DOMAIN-SUFFIX,hulu.com,美区影视 +- DOMAIN-SUFFIX,huluim.com,美区影视 +- DOMAIN-SUFFIX,hulustream.com,美区影视 +# > KKTV +# USER-AGENT,KKTV*,Global_media +# USER-AGENT,com.kktv.ios.kktv*,Global_media +- DOMAIN-SUFFIX,kktv.com.tw,Global_media +- DOMAIN-SUFFIX,kktv.me,Global_media +- DOMAIN,kktv-theater.kk.stream,Global_media +# > Line TV +# USER-AGENT,LINE%20TV*,Global_media +- DOMAIN-SUFFIX,linetv.tw,Global_media +- DOMAIN,d3c7rimkq79yfu.cloudfront.net,Global_media +# > Hulu(フールー) +- DOMAIN-SUFFIX,happyon.jp,Global_media +- DOMAIN-SUFFIX,hulu.jp,Global_media +# > LiTV +- DOMAIN-SUFFIX,litv.tv,Global_media +- DOMAIN,litvfreemobile-hichannel.cdn.hinet.net,Global_media +# > My5 +# USER-AGENT,My5*,GlobalMedia +- DOMAIN-SUFFIX,channel5.com,Global_media +- DOMAIN-SUFFIX,my5.tv,Global_media +- DOMAIN,d349g9zuie06uo.cloudfront.net,Global_media +# > myTV_SUPER +# USER-AGENT,mytv*,Global_media +- DOMAIN-SUFFIX,mytvsuper.com,Global_media +- DOMAIN-SUFFIX,tvb.com,Global_media +# > Netflix +# USER-AGENT,Argo*,netflix +- DOMAIN-SUFFIX,netflix.com,netflix +- DOMAIN-SUFFIX,netflix.net,netflix +- DOMAIN-SUFFIX,nflxext.com,netflix +- DOMAIN-SUFFIX,nflximg.com,netflix +- DOMAIN-SUFFIX,nflximg.net,netflix +- DOMAIN-SUFFIX,nflxso.net,netflix +- DOMAIN-SUFFIX,nflxvideo.net,netflix +- IP-CIDR,23.246.0.0/18,netflix +- IP-CIDR,37.77.184.0/21,netflix +- IP-CIDR,45.57.0.0/17,netflix +- IP-CIDR,64.120.128.0/17,netflix +- IP-CIDR,66.197.128.0/17,netflix +- IP-CIDR,108.175.32.0/20,netflix +- IP-CIDR,192.173.64.0/18,netflix +- IP-CIDR,198.38.96.0/19,netflix +- IP-CIDR,198.45.48.0/20,netflix +# > niconico +- DOMAIN-SUFFIX,dmc.nico,Global_media +- DOMAIN-SUFFIX,nicovideo.jp,Global_media +- DOMAIN-SUFFIX,nimg.jp,Global_media +- DOMAIN-SUFFIX,socdm.com,Global_media +# > PBS +# USER-AGENT,PBS*,Global_media +- DOMAIN-SUFFIX,pbs.org,Global_media +# > Pornhub +- DOMAIN-SUFFIX,phncdn.com,Global_media +- DOMAIN-SUFFIX,pornhub.com,Global_media +# > Twitch +- DOMAIN-SUFFIX,twitch.tv,Global_media +- DOMAIN-SUFFIX,twitchcdn.net,Global_media +- DOMAIN-SUFFIX,ttvnw.net,Global_media +# > Viu(TV) +# USER-AGENT,Viu*,Global_media +# USER-AGENT,ViuTV*,Global_media +- DOMAIN-SUFFIX,viu.com,Global_media +- DOMAIN-SUFFIX,viu.tv,Global_media +- DOMAIN,api.viu.now.com,Global_media +- DOMAIN,d1k2us671qcoau.cloudfront.net,Global_media +- DOMAIN,d2anahhhmp1ffz.cloudfront.net,Global_media +- DOMAIN,dfp6rglgjqszk.cloudfront.net,Global_media +# > Youtube +# USER-AGENT,com.google.ios.youtube*,google +# USER-AGENT,YouTube*,google +- DOMAIN-SUFFIX,googlevideo.com,google +- DOMAIN-SUFFIX,youtube.com,google +- DOMAIN,youtubei.googleapis.com,google + +# (Music) +# > Deezer +# USER-AGENT,Deezer*,Global_media +- DOMAIN-SUFFIX,deezer.com,Global_media +- DOMAIN-SUFFIX,dzcdn.net,Global_media +# > KKBOX +- DOMAIN-SUFFIX,kkbox.com,Global_media +- DOMAIN-SUFFIX,kkbox.com.tw,Global_media +- DOMAIN-SUFFIX,kfs.io,Global_media +# > JOOX +# USER-AGENT,WeMusic*,Global_media +# USER-AGENT,JOOX*,Global_media +- DOMAIN-SUFFIX,joox.com,Global_media +# > Pandora +# USER-AGENT,Pandora*,Global_media +- DOMAIN-SUFFIX,pandora.com,Global_media +# > Spotify +# USER-AGENT,Spotify*,Global_media +- DOMAIN-SUFFIX,pscdn.co,Global_media +- DOMAIN-SUFFIX,scdn.co,Global_media +- DOMAIN-SUFFIX,spotify.com,Global_media +- DOMAIN-SUFFIX,spoti.fi,Global_media +- IP-CIDR,35.186.224.47/32,Global_media +# > TIDAL +# USER-AGENT,TIDAL*,Global_media +- DOMAIN-SUFFIX,tidal.com,Global_media + + +# (DNS Cache Pollution Protection) +# > Google +- DOMAIN-SUFFIX,appspot.com,google +- DOMAIN-SUFFIX,blogger.com,google +- DOMAIN-SUFFIX,getoutline.org,google +- DOMAIN-SUFFIX,gvt0.com,google +- DOMAIN-SUFFIX,gvt1.com,google +- DOMAIN-SUFFIX,gvt3.com,google +- DOMAIN-SUFFIX,xn--ngstr-lra8j.com,google +- DOMAIN-KEYWORD,google,google +- DOMAIN-KEYWORD,blogspot,google +# > Microsoft +- DOMAIN-SUFFIX,onedrive.live.com,Proxy +- DOMAIN-SUFFIX,xboxlive.com,Proxy +# > Facebook +- DOMAIN-SUFFIX,cdninstagram.com,Proxy +- DOMAIN-SUFFIX,fb.com,Proxy +- DOMAIN-SUFFIX,fb.me,Proxy +- DOMAIN-SUFFIX,fbaddins.com,Proxy +- DOMAIN-SUFFIX,fbcdn.net,Proxy +- DOMAIN-SUFFIX,fbsbx.com,Proxy +- DOMAIN-SUFFIX,fbworkmail.com,Proxy +- DOMAIN-SUFFIX,instagram.com,Proxy +- DOMAIN-SUFFIX,m.me,Proxy +- DOMAIN-SUFFIX,messenger.com,Proxy +- DOMAIN-SUFFIX,oculus.com,Proxy +- DOMAIN-SUFFIX,oculuscdn.com,Proxy +- DOMAIN-SUFFIX,rocksdb.org,Proxy +- DOMAIN-SUFFIX,whatsapp.com,Proxy +- DOMAIN-SUFFIX,whatsapp.net,Proxy +- DOMAIN-KEYWORD,facebook,Proxy +# > Twitter +- DOMAIN-SUFFIX,pscp.tv,Proxy +- DOMAIN-SUFFIX,periscope.tv,Proxy +- DOMAIN-SUFFIX,t.co,Proxy +- DOMAIN-SUFFIX,twimg.co,Proxy +- DOMAIN-SUFFIX,twimg.com,Proxy +- DOMAIN-SUFFIX,twitpic.com,Proxy +- DOMAIN-SUFFIX,vine.co,Proxy +- DOMAIN-KEYWORD,twitter,Proxy +# > Telegram +- DOMAIN-SUFFIX,t.me,Telegram +- DOMAIN-SUFFIX,tdesktop.com,Telegram +- DOMAIN-SUFFIX,telegra.ph,Telegram +- DOMAIN-SUFFIX,telegram.me,Telegram +- DOMAIN-SUFFIX,telegram.org,Telegram +- IP-CIDR,67.198.55.0/24,Telegram +- IP-CIDR,91.108.4.0/22,Telegram +- IP-CIDR,91.108.8.0/22,Telegram +- IP-CIDR,91.108.12.0/22,Telegram +- IP-CIDR,91.108.16.0/22,Telegram +- IP-CIDR,91.108.56.0/22,Telegram +- IP-CIDR,109.239.140.0/24,Telegram +- IP-CIDR,149.154.160.0/20,Telegram +- IP-CIDR,205.172.60.0/22,Telegram +- DOMAIN-SUFFIX,t.me,Telegram +- DOMAIN-SUFFIX,tdesktop.com,Telegram +- DOMAIN-SUFFIX,telegra.ph,Telegram +- DOMAIN-SUFFIX,telegram.me,Telegram +- DOMAIN-SUFFIX,telegram.org,Telegram +- DOMAIN-SUFFIX,t.me,Telegram +- IP-CIDR,67.198.55.0/24,Telegram +- IP-CIDR,91.108.4.0/22,Telegram +- IP-CIDR,91.108.8.0/22,Telegram +- IP-CIDR,91.108.12.0/22,Telegram +- IP-CIDR,91.108.16.0/22,Telegram +- IP-CIDR,91.108.56.150/32,Telegram +- IP-CIDR,91.108.56.141/32,Telegram +- IP-CIDR,109.239.140.0/24,Telegram +- IP-CIDR,149.154.160.0/20,Telegram +- IP-CIDR,149.154.164.250/32,Telegram +- IP-CIDR,149.154.175.51/32,Telegram +- IP-CIDR,149.154.175.53/32,Telegram +- IP-CIDR,149.154.167.50/32,Telegram +- IP-CIDR,149.154.167.51/32,Telegram +- IP-CIDR,172.217.160.74/32,Telegram +- IP-CIDR,205.172.60.0/22,Telegram +# > Line +- DOMAIN-SUFFIX,line.me,Proxy +- DOMAIN-SUFFIX,line-apps.com,Proxy +- DOMAIN-SUFFIX,line-scdn.net,Proxy +- DOMAIN-SUFFIX,naver.jp,Proxy +- IP-CIDR,103.2.30.0/23,Proxy +- IP-CIDR,125.209.208.0/20,Proxy +- IP-CIDR,147.92.128.0/17,Proxy +- IP-CIDR,203.104.144.0/21,Proxy +# > Other +- DOMAIN-SUFFIX,4shared.com,Proxy +- DOMAIN-SUFFIX,881903.com,Proxy +- DOMAIN-SUFFIX,9cache.com,Proxy +- DOMAIN-SUFFIX,9gag.com,Proxy +- DOMAIN-SUFFIX,abc.com,Proxy +- DOMAIN-SUFFIX,abc.net.au,Proxy +- DOMAIN-SUFFIX,abebooks.com,Proxy +- DOMAIN-SUFFIX,amazon.co.jp,Proxy +- DOMAIN-SUFFIX,apigee.com,Proxy +- DOMAIN-SUFFIX,apk-dl.com,Proxy +- DOMAIN-SUFFIX,apkfind.com,Proxy +- DOMAIN-SUFFIX,apkmirror.com,Proxy +- DOMAIN-SUFFIX,apkmonk.com,Proxy +- DOMAIN-SUFFIX,apkpure.com,Proxy +- DOMAIN-SUFFIX,aptoide.com,Proxy +- DOMAIN-SUFFIX,archive.is,Proxy +- DOMAIN-SUFFIX,archive.org,Proxy +- DOMAIN-SUFFIX,arte.tv,Proxy +- DOMAIN-SUFFIX,artstation.com,Proxy +- DOMAIN-SUFFIX,ask.com,Proxy +- DOMAIN-SUFFIX,arukas.io,Proxy +- DOMAIN-SUFFIX,avgle.com,Proxy +- DOMAIN-SUFFIX,badoo.com,Proxy +- DOMAIN-SUFFIX,bandwagonhost.com,Proxy +- DOMAIN-SUFFIX,bbc.com,Proxy +- DOMAIN-SUFFIX,behance.net,Proxy +- DOMAIN-SUFFIX,bibox.com,Proxy +- DOMAIN-SUFFIX,biggo.com.tw,Proxy +- DOMAIN-SUFFIX,binance.com,Proxy +- DOMAIN-SUFFIX,bitcointalk.org,Proxy +- DOMAIN-SUFFIX,bitfinex.com,Proxy +- DOMAIN-SUFFIX,bitmex.com,Proxy +- DOMAIN-SUFFIX,bit-z.com,Proxy +- DOMAIN-SUFFIX,bloglovin.com,Proxy +- DOMAIN-SUFFIX,bloomberg.cn,Proxy +- DOMAIN-SUFFIX,bloomberg.com,Proxy +- DOMAIN-SUFFIX,blubrry.com,Proxy +- DOMAIN-SUFFIX,book.com.tw,Proxy +- DOMAIN-SUFFIX,booklive.jp,Proxy +- DOMAIN-SUFFIX,books.com.tw,Proxy +- DOMAIN-SUFFIX,box.com,Proxy +- DOMAIN-SUFFIX,businessinsider.com,Proxy +- DOMAIN-SUFFIX,bwh1.net,Proxy +- DOMAIN-SUFFIX,castbox.fm,Proxy +- DOMAIN-SUFFIX,cbc.ca,Proxy +- DOMAIN-SUFFIX,cccat.cc,Proxy +- DOMAIN-SUFFIX,cdw.com,Proxy +- DOMAIN-SUFFIX,change.org,Proxy +- DOMAIN-SUFFIX,ck101.com,Proxy +- DOMAIN-SUFFIX,clarionproject.org,Proxy +- DOMAIN-SUFFIX,clyp.it,Proxy +- DOMAIN-SUFFIX,cna.com.tw,Proxy +- DOMAIN-SUFFIX,comparitech.com,Proxy +- DOMAIN-SUFFIX,conoha.jp,Proxy +- DOMAIN-SUFFIX,crucial.com,Proxy +- DOMAIN-SUFFIX,cts.com.tw,Proxy +- DOMAIN-SUFFIX,cw.com.tw,Proxy +- DOMAIN-SUFFIX,cyberctm.com,Proxy +- DOMAIN-SUFFIX,dailymotion.com,Proxy +- DOMAIN-SUFFIX,dailyview.tw,Proxy +- DOMAIN-SUFFIX,daum.net,Proxy +- DOMAIN-SUFFIX,daumcdn.net,Proxy +- DOMAIN-SUFFIX,dcard.tw,Proxy +- DOMAIN-SUFFIX,deepdiscount.com,Proxy +- DOMAIN-SUFFIX,depositphotos.com,Proxy +- DOMAIN-SUFFIX,deviantart.com,Proxy +- DOMAIN-SUFFIX,disconnect.me,Proxy +- DOMAIN-SUFFIX,discordapp.com,Proxy +- DOMAIN-SUFFIX,discordapp.net,Proxy +- DOMAIN-SUFFIX,disqus.com,Proxy +- DOMAIN-SUFFIX,dns2go.com,Proxy +- DOMAIN-SUFFIX,dropbox.com,Proxy +- DOMAIN-SUFFIX,dropboxusercontent.com,Proxy +- DOMAIN-SUFFIX,duckduckgo.com,Proxy +- DOMAIN-SUFFIX,dw.com,Proxy +- DOMAIN-SUFFIX,dynu.com,Proxy +- DOMAIN-SUFFIX,earthcam.com,Proxy +- DOMAIN-SUFFIX,ebookservice.tw,Proxy +- DOMAIN-SUFFIX,economist.com,Proxy +- DOMAIN-SUFFIX,edgecastcdn.net,Proxy +- DOMAIN-SUFFIX,edu,Proxy +- DOMAIN-SUFFIX,elpais.com,Proxy +- DOMAIN-SUFFIX,enanyang.my,Proxy +- DOMAIN-SUFFIX,esoir.be,Proxy +- DOMAIN-SUFFIX,euronews.com,Proxy +- DOMAIN-SUFFIX,feedly.com,Proxy +- DOMAIN-SUFFIX,firech.at,Proxy +- DOMAIN-SUFFIX,flickr.com,Proxy +- DOMAIN-SUFFIX,flitto.com,Proxy +- DOMAIN-SUFFIX,foreignpolicy.com,Proxy +- DOMAIN-SUFFIX,friday.tw,Proxy +- DOMAIN-SUFFIX,gate.io,Proxy +- DOMAIN-SUFFIX,getlantern.org,Proxy +- DOMAIN-SUFFIX,getsync.com,Proxy +- DOMAIN-SUFFIX,globalvoices.org,Proxy +- DOMAIN-SUFFIX,goo.ne.jp,Proxy +- DOMAIN-SUFFIX,goodreads.com,Proxy +- DOMAIN-SUFFIX,gov,Proxy +- DOMAIN-SUFFIX,gov.tw,Proxy +- DOMAIN-SUFFIX,gumroad.com,Proxy +- DOMAIN-SUFFIX,hbg.com,Proxy +- DOMAIN-SUFFIX,heroku.com,Proxy +- DOMAIN-SUFFIX,hightail.com,Proxy +- DOMAIN-SUFFIX,hk01.com,Proxy +- DOMAIN-SUFFIX,hkbf.org,Proxy +- DOMAIN-SUFFIX,hkbookcity.com,Proxy +- DOMAIN-SUFFIX,hkej.com,Proxy +- DOMAIN-SUFFIX,hket.com,Proxy +- DOMAIN-SUFFIX,hkgolden.com,Proxy +- DOMAIN-SUFFIX,hootsuite.com,Proxy +- DOMAIN-SUFFIX,hudson.org,Proxy +- DOMAIN-SUFFIX,hyread.com.tw,Proxy +- DOMAIN-SUFFIX,ibtimes.com,Proxy +- DOMAIN-SUFFIX,i-cable.com,Proxy +- DOMAIN-SUFFIX,icij.org,Proxy +- DOMAIN-SUFFIX,icoco.com,Proxy +- DOMAIN-SUFFIX,imgur.com,Proxy +- DOMAIN-SUFFIX,initiummall.com,Proxy +- DOMAIN-SUFFIX,insecam.org,Proxy +- DOMAIN-SUFFIX,ipfs.io,Proxy +- DOMAIN-SUFFIX,issuu.com,Proxy +- DOMAIN-SUFFIX,istockphoto.com,Proxy +- DOMAIN-SUFFIX,japantimes.co.jp,Proxy +- DOMAIN-SUFFIX,jiji.com,Proxy +- DOMAIN-SUFFIX,jinx.com,Proxy +- DOMAIN-SUFFIX,jkforum.net,Proxy +- DOMAIN-SUFFIX,joinmastodon.org,Proxy +- DOMAIN-SUFFIX,justpaste.it,Proxy +- DOMAIN-SUFFIX,kakao.com,Proxy +- DOMAIN-SUFFIX,kakaocorp.com,Proxy +- DOMAIN-SUFFIX,kik.com,Proxy +- DOMAIN-SUFFIX,kobo.com,Proxy +- DOMAIN-SUFFIX,kobobooks.com,Proxy +- DOMAIN-SUFFIX,kodingen.com,Proxy +- DOMAIN-SUFFIX,lemonde.fr,Proxy +- DOMAIN-SUFFIX,lepoint.fr,Proxy +- DOMAIN-SUFFIX,lihkg.com,Proxy +- DOMAIN-SUFFIX,listennotes.com,Proxy +- DOMAIN-SUFFIX,livestream.com,Proxy +- DOMAIN-SUFFIX,logmein.com,Proxy +- DOMAIN-SUFFIX,mail.ru,Proxy +- DOMAIN-SUFFIX,mailchimp.com,Proxy +- DOMAIN-SUFFIX,marc.info,Proxy +- DOMAIN-SUFFIX,matters.news,Proxy +- DOMAIN-SUFFIX,medium.com,Proxy +- DOMAIN-SUFFIX,mega.nz,Proxy +- DOMAIN-SUFFIX,mil,Proxy +- DOMAIN-SUFFIX,mingpao.com,Proxy +- DOMAIN-SUFFIX,mobile01.com,Proxy +- DOMAIN-SUFFIX,myspace.com,Proxy +- DOMAIN-SUFFIX,myspacecdn.com,Proxy +- DOMAIN-SUFFIX,nanyang.com,Proxy +- DOMAIN-SUFFIX,naver.com,Proxy +- DOMAIN-SUFFIX,newstapa.org,Proxy +- DOMAIN-SUFFIX,nhk.or.jp,Proxy +- DOMAIN-SUFFIX,nicovideo.jp,Proxy +- DOMAIN-SUFFIX,nii.ac.jp,Proxy +- DOMAIN-SUFFIX,nikkei.com,Proxy +- DOMAIN-SUFFIX,nofile.io,Proxy +- DOMAIN-SUFFIX,now.com,Proxy +- DOMAIN-SUFFIX,nrk.no,Proxy +- DOMAIN-SUFFIX,nyt.com,Proxy +- DOMAIN-SUFFIX,nytchina.com,Proxy +- DOMAIN-SUFFIX,nytcn.me,Proxy +- DOMAIN-SUFFIX,nytco.com,Proxy +- DOMAIN-SUFFIX,nytimes.com,Proxy +- DOMAIN-SUFFIX,nytimg.com,Proxy +- DOMAIN-SUFFIX,nytlog.com,Proxy +- DOMAIN-SUFFIX,nytstyle.com,Proxy +- DOMAIN-SUFFIX,ok.ru,Proxy +- DOMAIN-SUFFIX,okex.com,Proxy +- DOMAIN-SUFFIX,on.cc,Proxy +- DOMAIN-SUFFIX,orientaldaily.com.my,Proxy +- DOMAIN-SUFFIX,overcast.fm,Proxy +- DOMAIN-SUFFIX,paltalk.com,Proxy +- DOMAIN-SUFFIX,pbxes.com,Proxy +- DOMAIN-SUFFIX,pcdvd.com.tw,Proxy +- DOMAIN-SUFFIX,pchome.com.tw,Proxy +- DOMAIN-SUFFIX,pcloud.com,Proxy +- DOMAIN-SUFFIX,picacomic.com,Proxy +- DOMAIN-SUFFIX,pinimg.com,Proxy +- DOMAIN-SUFFIX,pixiv.net,Proxy +- DOMAIN-SUFFIX,player.fm,Proxy +- DOMAIN-SUFFIX,plurk.com,Proxy +- DOMAIN-SUFFIX,po18.tw,Proxy +- DOMAIN-SUFFIX,prism-break.org,Proxy +- DOMAIN-SUFFIX,proxifier.com,Proxy +- DOMAIN-SUFFIX,pts.org.tw,Proxy +- DOMAIN-SUFFIX,pubu.com.tw,Proxy +- DOMAIN-SUFFIX,pubu.tw,Proxy +- DOMAIN-SUFFIX,pureapk.com,Proxy +- DOMAIN-SUFFIX,quora.com,Proxy +- DOMAIN-SUFFIX,quoracdn.net,Proxy +- DOMAIN-SUFFIX,rakuten.co.jp,Proxy +- DOMAIN-SUFFIX,readingtimes.com.tw,Proxy +- DOMAIN-SUFFIX,readmoo.com,Proxy +- DOMAIN-SUFFIX,reddit.com,Proxy +- DOMAIN-SUFFIX,redditmedia.com,Proxy +- DOMAIN-SUFFIX,resilio.com,Proxy +- DOMAIN-SUFFIX,reuters.com,Proxy +- DOMAIN-SUFFIX,rfi.fr,Proxy +- DOMAIN-SUFFIX,roadshow.hk,Proxy +- DOMAIN-SUFFIX,scmp.com,Proxy +- DOMAIN-SUFFIX,scribd.com,Proxy +- DOMAIN-SUFFIX,seatguru.com,Proxy +- DOMAIN-SUFFIX,shadowsocks.org,Proxy +- DOMAIN-SUFFIX,shopee.tw,Proxy +- DOMAIN-SUFFIX,slideshare.net,Proxy +- DOMAIN-SUFFIX,softfamous.com,Proxy +- DOMAIN-SUFFIX,soundcloud.com,Proxy +- DOMAIN-SUFFIX,startpage.com,Proxy +- DOMAIN-SUFFIX,steamcommunity.com,Proxy +- DOMAIN-SUFFIX,steemit.com,Proxy +- DOMAIN-SUFFIX,steemitwallet.com,Proxy +- DOMAIN-SUFFIX,t66y.com,Proxy +- DOMAIN-SUFFIX,tapatalk.com,Proxy +- DOMAIN-SUFFIX,teco-hk.org,Proxy +- DOMAIN-SUFFIX,teco-mo.org,Proxy +- DOMAIN-SUFFIX,teddysun.com,Proxy +- DOMAIN-SUFFIX,theguardian.com,Proxy +- DOMAIN-SUFFIX,theinitium.com,Proxy +- DOMAIN-SUFFIX,tineye.com,Proxy +- DOMAIN-SUFFIX,torproject.org,Proxy +- DOMAIN-SUFFIX,tumblr.com,Proxy +- DOMAIN-SUFFIX,turbobit.net,Proxy +- DOMAIN-SUFFIX,tutanota.com,Proxy +- DOMAIN-SUFFIX,tvboxnow.com,Proxy +- DOMAIN-SUFFIX,udn.com,Proxy +- DOMAIN-SUFFIX,unseen.is,Proxy +- DOMAIN-SUFFIX,upmedia.mg,Proxy +- DOMAIN-SUFFIX,uptodown.com,Proxy +- DOMAIN-SUFFIX,ustream.tv,Proxy +- DOMAIN-SUFFIX,uwants.com,Proxy +- DOMAIN-SUFFIX,v2ray.com,Proxy +- DOMAIN-SUFFIX,viber.com,Proxy +- DOMAIN-SUFFIX,videopress.com,Proxy +- DOMAIN-SUFFIX,vimeo.com,Proxy +- DOMAIN-SUFFIX,voachinese.com,Proxy +- DOMAIN-SUFFIX,voanews.com,Proxy +- DOMAIN-SUFFIX,voxer.com,Proxy +- DOMAIN-SUFFIX,vzw.com,Proxy +- DOMAIN-SUFFIX,w3schools.com,Proxy +- DOMAIN-SUFFIX,washingtonpost.com,Proxy +- DOMAIN-SUFFIX,wattpad.com,Proxy +- DOMAIN-SUFFIX,whoer.net,Proxy +- DOMAIN-SUFFIX,wikimapia.org,Proxy +- DOMAIN-SUFFIX,wikipedia.org,Proxy +- DOMAIN-SUFFIX,winudf.com,Proxy +- DOMAIN-SUFFIX,wire.com,Proxy +- DOMAIN-SUFFIX,wordpress.com,Proxy +- DOMAIN-SUFFIX,workflow.is,Proxy +- DOMAIN-SUFFIX,worldcat.org,Proxy +- DOMAIN-SUFFIX,wsj.com,Proxy +- DOMAIN-SUFFIX,wsj.net,Proxy +- DOMAIN-SUFFIX,xhamster.com,Proxy +- DOMAIN-SUFFIX,xnxx.com,Proxy +- DOMAIN-SUFFIX,xvideos.com,Proxy +- DOMAIN-SUFFIX,yahoo.com,Proxy +- DOMAIN-SUFFIX,yandex.ru,Proxy +- DOMAIN-SUFFIX,yesasia.com,Proxy +- DOMAIN-SUFFIX,yes-news.com,Proxy +- DOMAIN-SUFFIX,yomiuri.co.jp,Proxy +- DOMAIN-SUFFIX,you-get.org,Proxy +- DOMAIN-SUFFIX,zaobao.com,Proxy +- DOMAIN-SUFFIX,zb.com,Proxy +- DOMAIN-SUFFIX,zello.com,Proxy +- DOMAIN-SUFFIX,zeronet.io,Proxy +- DOMAIN-KEYWORD,github,Proxy +- DOMAIN-KEYWORD,jav,Proxy +- DOMAIN-KEYWORD,pinterest,Proxy +- DOMAIN-KEYWORD,porn,Proxy +- DOMAIN-KEYWORD,wikileaks,Proxy + +# (Region-Restricted Access Denied) +- DOMAIN-SUFFIX,apartmentratings.com,Proxy +- DOMAIN-SUFFIX,apartments.com,Proxy +- DOMAIN-SUFFIX,bankmobilevibe.com,Proxy +- DOMAIN-SUFFIX,bing.com,Proxy +- DOMAIN-SUFFIX,booktopia.com.au,Proxy +- DOMAIN-SUFFIX,centauro.com.br,Proxy +- DOMAIN-SUFFIX,clearsurance.com,Proxy +- DOMAIN-SUFFIX,costco.com,Proxy +- DOMAIN-SUFFIX,crackle.com,Proxy +- DOMAIN-SUFFIX,depositphotos.cn,Proxy +- DOMAIN-SUFFIX,dish.com,Proxy +- DOMAIN-SUFFIX,dmm.co.jp,Proxy +- DOMAIN-SUFFIX,dmm.com,Proxy +- DOMAIN-SUFFIX,dnvod.tv,Proxy +- DOMAIN-SUFFIX,esurance.com,Proxy +- DOMAIN-SUFFIX,extmatrix.com,Proxy +- DOMAIN-SUFFIX,fastpic.ru,Proxy +- DOMAIN-SUFFIX,flipboard.com,Proxy +- DOMAIN-SUFFIX,fnac.be,Proxy +- DOMAIN-SUFFIX,fnac.com,Proxy +- DOMAIN-SUFFIX,funkyimg.com,Proxy +- DOMAIN-SUFFIX,fxnetworks.com,Proxy +- DOMAIN-SUFFIX,gettyimages.com,Proxy +- DOMAIN-SUFFIX,go.com,Proxy +- DOMAIN-SUFFIX,here.com,Proxy +- DOMAIN-SUFFIX,jcpenney.com,Proxy +- DOMAIN-SUFFIX,jiehua.tv,Proxy +- DOMAIN-SUFFIX,kknews.cc,Proxy +- DOMAIN-SUFFIX,mailfence.com,Proxy +- DOMAIN-SUFFIX,nationwide.com,Proxy +- DOMAIN-SUFFIX,nbc.com,Proxy +- DOMAIN-SUFFIX,nexon.com,Proxy +- DOMAIN-SUFFIX,nordstrom.com,Proxy +- DOMAIN-SUFFIX,nordstromimage.com,Proxy +- DOMAIN-SUFFIX,nordstromrack.com,Proxy +- DOMAIN-SUFFIX,read01.com,Proxy +- DOMAIN-SUFFIX,superpages.com,Proxy +- DOMAIN-SUFFIX,target.com,Proxy +- DOMAIN-SUFFIX,thinkgeek.com,Proxy +- DOMAIN-SUFFIX,tracfone.com,Proxy +- DOMAIN-SUFFIX,uploader.jp,Proxy +- DOMAIN-SUFFIX,vevo.com,Proxy +- DOMAIN-SUFFIX,viu.tv,Proxy +- DOMAIN-SUFFIX,vk.com,Proxy +- DOMAIN-SUFFIX,vsco.co,Proxy +- DOMAIN-SUFFIX,xfinity.com,Proxy +- DOMAIN-SUFFIX,zattoo.com,Proxy +# USER-AGENT,Roam*,Proxy + +# (The Most Popular Sites) +# > Apple +# >> TestFlight +- DOMAIN,testflight.apple.com,Apple +# >> Apple URL Shortener +- DOMAIN-SUFFIX,appsto.re,Apple +# >> iBooks Store download +- DOMAIN,books.itunes.apple.com,Apple +# >> iTunes Store Moveis Trailers +- DOMAIN,hls.itunes.apple.com,Apple +# >> App Store Preview +- DOMAIN,apps.apple.com,Apple +- DOMAIN,itunes.apple.com,Apple +# >> Spotlight +- DOMAIN,api-glb-sea.smoot.apple.com,Apple +# >> Dictionary +- DOMAIN,lookup-api.apple.com,Apple +# >> Apple News and Apple Map TOMTOM Version +- DOMAIN,gspe1-ssl.ls.apple.com,Apple +# USER-AGENT,AppleNews*,Apple +# USER-AGENT,com.apple.news*,Apple +- DOMAIN-SUFFIX,apple.news,Apple +- DOMAIN,news-client.apple.com,Apple +- DOMAIN,news-edge.apple.com,Apple +- DOMAIN,news-events.apple.com,Apple +- DOMAIN,apple.comscoreresearch.com,Apple +# > Google +- DOMAIN-SUFFIX,abc.xyz,google +- DOMAIN-SUFFIX,android.com,google +- DOMAIN-SUFFIX,androidify.com,google +- DOMAIN-SUFFIX,dialogflow.com,google +- DOMAIN-SUFFIX,autodraw.com,google +- DOMAIN-SUFFIX,capitalg.com,google +- DOMAIN-SUFFIX,certificate-transparency.org,google +- DOMAIN-SUFFIX,chrome.com,google +- DOMAIN-SUFFIX,chromeexperiments.com,google +- DOMAIN-SUFFIX,chromestatus.com,google +- DOMAIN-SUFFIX,chromium.org,google +- DOMAIN-SUFFIX,creativelab5.com,google +- DOMAIN-SUFFIX,debug.com,google +- DOMAIN-SUFFIX,deepmind.com,google +- DOMAIN-SUFFIX,firebaseio.com,google +- DOMAIN-SUFFIX,getmdl.io,google +- DOMAIN-SUFFIX,ggpht.com,google +- DOMAIN-SUFFIX,gmail.com,google +- DOMAIN-SUFFIX,gmodules.com,google +- DOMAIN-SUFFIX,godoc.org,google +- DOMAIN-SUFFIX,golang.org,google +- DOMAIN-SUFFIX,gstatic.com,google +- DOMAIN-SUFFIX,gv.com,google +- DOMAIN-SUFFIX,gwtproject.org,google +- DOMAIN-SUFFIX,itasoftware.com,google +- DOMAIN-SUFFIX,madewithcode.com,google +- DOMAIN-SUFFIX,material.io,google +- DOMAIN-SUFFIX,polymer-project.org,google +- DOMAIN-SUFFIX,admin.recaptcha.net,google +- DOMAIN-SUFFIX,recaptcha.net,google +- DOMAIN-SUFFIX,shattered.io,google +- DOMAIN-SUFFIX,synergyse.com,google +- DOMAIN-SUFFIX,tensorflow.org,google +- DOMAIN-SUFFIX,tfhub.dev,google +- DOMAIN-SUFFIX,tiltbrush.com,google +- DOMAIN-SUFFIX,waveprotocol.org,google +- DOMAIN-SUFFIX,waymo.com,google +- DOMAIN-SUFFIX,webmproject.org,google +- DOMAIN-SUFFIX,webrtc.org,google +- DOMAIN-SUFFIX,whatbrowser.org,google +- DOMAIN-SUFFIX,widevine.com,google +- DOMAIN-SUFFIX,x.company,google +- DOMAIN-SUFFIX,youtu.be,google +- DOMAIN-SUFFIX,yt.be,google +- DOMAIN-SUFFIX,ytimg.com,google +# > Microsoft +- DOMAIN-SUFFIX,1drv.com,Proxy +- DOMAIN-SUFFIX,1drv.ms,Proxy +- DOMAIN-SUFFIX,live.com,Proxy +- DOMAIN-SUFFIX,live.net,Proxy +- DOMAIN-SUFFIX,livefilestore.com,Proxy +- DOMAIN-SUFFIX,storage.msn.com,Proxy +# > Other +- DOMAIN-SUFFIX,0rz.tw,Proxy +- DOMAIN-SUFFIX,4bluestones.biz,Proxy +- DOMAIN-SUFFIX,9bis.net,Proxy +- DOMAIN-SUFFIX,allconnected.co,Proxy +- DOMAIN-SUFFIX,amazonaws.com,Proxy +- DOMAIN-SUFFIX,aol.com,Proxy +- DOMAIN-SUFFIX,bcc.com.tw,Proxy +- DOMAIN-SUFFIX,bit.ly,Proxy +- DOMAIN-SUFFIX,bitshare.com,Proxy +- DOMAIN-SUFFIX,blog.jp,Proxy +- DOMAIN-SUFFIX,blogimg.jp,Proxy +- DOMAIN-SUFFIX,blogtd.org,Proxy +- DOMAIN-SUFFIX,broadcast.co.nz,Proxy +- DOMAIN-SUFFIX,camfrog.com,Proxy +- DOMAIN-SUFFIX,cfos.de,Proxy +- DOMAIN-SUFFIX,citypopulation.de,Proxy +- DOMAIN-SUFFIX,cloudfront.net,Proxy +- DOMAIN-SUFFIX,ctitv.com.tw,Proxy +- DOMAIN-SUFFIX,cuhk.edu.hk,Proxy +- DOMAIN-SUFFIX,cusu.hk,Proxy +- DOMAIN-SUFFIX,discuss.com.hk,Proxy +- DOMAIN-SUFFIX,dropboxapi.com,Proxy +- DOMAIN-SUFFIX,duolingo.cn,Proxy +- DOMAIN-SUFFIX,edditstatic.com,Proxy +- DOMAIN-SUFFIX,flickriver.com,Proxy +- DOMAIN-SUFFIX,focustaiwan.tw,Proxy +- DOMAIN-SUFFIX,free.fr,Proxy +- DOMAIN-SUFFIX,ftchinese.com,Proxy +- DOMAIN-SUFFIX,gigacircle.com,Proxy +- DOMAIN-SUFFIX,hk-pub.com,Proxy +- DOMAIN-SUFFIX,hosting.co.uk,Proxy +- DOMAIN-SUFFIX,hwcdn.net,Proxy +- DOMAIN-SUFFIX,iphone4hongkong.com,Proxy +- DOMAIN-SUFFIX,iphonetaiwan.org,Proxy +- DOMAIN-SUFFIX,iptvbin.com,Proxy +- DOMAIN-SUFFIX,jtvnw.net,Proxy +- DOMAIN-SUFFIX,linksalpha.com,Proxy +- DOMAIN-SUFFIX,manyvids.com,Proxy +- DOMAIN-SUFFIX,myactimes.com,Proxy +- DOMAIN-SUFFIX,newsblur.com,Proxy +- DOMAIN-SUFFIX,now.im,Proxy +- DOMAIN-SUFFIX,redditlist.com,Proxy +- DOMAIN-SUFFIX,smartmailcloud.com,Proxy +- DOMAIN-SUFFIX,signal.org,Proxy +- DOMAIN-SUFFIX,sparknotes.com,Proxy +- DOMAIN-SUFFIX,streetvoice.com,Proxy +- DOMAIN-SUFFIX,supertop.co,Proxy +- DOMAIN-SUFFIX,tv.com,Proxy +- DOMAIN-SUFFIX,typepad.com,Proxy +- DOMAIN-SUFFIX,udnbkk.com,Proxy +- DOMAIN-SUFFIX,whispersystems.org,Proxy +- DOMAIN-SUFFIX,wikia.com,Proxy +- DOMAIN-SUFFIX,wn.com,Proxy +- DOMAIN-SUFFIX,wolframalpha.com,Proxy +- DOMAIN-SUFFIX,x-art.com,Proxy +- DOMAIN-SUFFIX,yimg.com,Proxy +# China Area Network +# > 360 +- DOMAIN-SUFFIX,qhres.com,DIRECT +- DOMAIN-SUFFIX,qhimg.com,DIRECT +# > Akamai +- DOMAIN-SUFFIX,akadns.net,DIRECT +# - DOMAIN-SUFFIX,akamai.net,DIRECT +# - DOMAIN-SUFFIX,akamaiedge.net,DIRECT +# - DOMAIN-SUFFIX,akamaihd.net,DIRECT +# - DOMAIN-SUFFIX,akamaistream.net,DIRECT +# - DOMAIN-SUFFIX,akamaized.net,DIRECT +# > Alibaba +# USER-AGENT,%E4%BC%98%E9%85%B7*,DIRECT +- DOMAIN-SUFFIX,alibaba.com,DIRECT +- DOMAIN-SUFFIX,alicdn.com,DIRECT +- DOMAIN-SUFFIX,alikunlun.com,DIRECT +- DOMAIN-SUFFIX,alipay.com,DIRECT +- DOMAIN-SUFFIX,amap.com,DIRECT +- DOMAIN-SUFFIX,autonavi.com,DIRECT +- DOMAIN-SUFFIX,dingtalk.com,DIRECT +- DOMAIN-SUFFIX,mxhichina.com,DIRECT +- DOMAIN-SUFFIX,soku.com,DIRECT +- DOMAIN-SUFFIX,taobao.com,DIRECT +- DOMAIN-SUFFIX,tmall.com,DIRECT +- DOMAIN-SUFFIX,tmall.hk,DIRECT +- DOMAIN-SUFFIX,ykimg.com,DIRECT +- DOMAIN-SUFFIX,youku.com,DIRECT +- DOMAIN-SUFFIX,xiami.com,DIRECT +- DOMAIN-SUFFIX,xiami.net,DIRECT +# > Baidu +- DOMAIN-SUFFIX,baidu.com,DIRECT +- DOMAIN-SUFFIX,baidubcr.com,DIRECT +- DOMAIN-SUFFIX,bdstatic.com,DIRECT +- DOMAIN-SUFFIX,yunjiasu-cdn.net,DIRECT +# > bilibili +- DOMAIN-SUFFIX,acgvideo.com,DIRECT +- DOMAIN-SUFFIX,biliapi.com,DIRECT +- DOMAIN-SUFFIX,biliapi.net,DIRECT +- DOMAIN-SUFFIX,bilibili.com,DIRECT +- DOMAIN-SUFFIX,bilibili.tv,DIRECT +- DOMAIN-SUFFIX,hdslb.com,DIRECT +# > Blizzard +- DOMAIN-SUFFIX,blizzard.com,DIRECT +- DOMAIN-SUFFIX,battle.net,DIRECT +- DOMAIN,blzddist1-a.akamaihd.net,DIRECT +# > ByteDance +- DOMAIN-SUFFIX,feiliao.com,DIRECT +- DOMAIN-SUFFIX,pstatp.com,DIRECT +- DOMAIN-SUFFIX,snssdk.com,DIRECT +- DOMAIN-SUFFIX,iesdouyin.com,DIRECT +- DOMAIN-SUFFIX,toutiao.com,DIRECT +# > CCTV +- DOMAIN-SUFFIX,cctv.com,DIRECT +- DOMAIN-SUFFIX,cctvpic.com,DIRECT +- DOMAIN-SUFFIX,livechina.com,DIRECT +# > DiDi +- DOMAIN-SUFFIX,didialift.com,DIRECT +- DOMAIN-SUFFIX,didiglobal.com,DIRECT +- DOMAIN-SUFFIX,udache.com,DIRECT +# > 蛋蛋赞 +- DOMAIN-SUFFIX,343480.com,DIRECT +- DOMAIN-SUFFIX,baduziyuan.com,DIRECT +- DOMAIN-SUFFIX,com-hs-hkdy.com,DIRECT +- DOMAIN-SUFFIX,czybjz.com,DIRECT +- DOMAIN-SUFFIX,dandanzan.com,DIRECT +- DOMAIN-SUFFIX,fjhps.com,DIRECT +- DOMAIN-SUFFIX,kuyunbo.club,DIRECT +# > ChinaNet +- DOMAIN-SUFFIX,21cn.com,DIRECT +# > HunanTV +- DOMAIN-SUFFIX,hitv.com,DIRECT +- DOMAIN-SUFFIX,mgtv.com,DIRECT +# > iQiyi +- DOMAIN-SUFFIX,iqiyi.com,DIRECT +- DOMAIN-SUFFIX,iqiyipic.com,DIRECT +- DOMAIN-SUFFIX,71.am.com,DIRECT +# > JD +- DOMAIN-SUFFIX,jd.com,DIRECT +- DOMAIN-SUFFIX,jd.hk,DIRECT +- DOMAIN-SUFFIX,jdpay.com,DIRECT +- DOMAIN-SUFFIX,360buyimg.com,DIRECT +# > Kingsoft +- DOMAIN-SUFFIX,iciba.com,DIRECT +- DOMAIN-SUFFIX,ksosoft.com,DIRECT +# > Meitu +- DOMAIN-SUFFIX,meitu.com,DIRECT +- DOMAIN-SUFFIX,meitudata.com,DIRECT +- DOMAIN-SUFFIX,meitustat.com,DIRECT +- DOMAIN-SUFFIX,meipai.com,DIRECT +# > MI +- DOMAIN-SUFFIX,duokan.com,DIRECT +- DOMAIN-SUFFIX,mi-img.com,DIRECT +- DOMAIN-SUFFIX,miui.com,DIRECT +- DOMAIN-SUFFIX,miwifi.com,DIRECT +- DOMAIN-SUFFIX,xiaomi.com,DIRECT +# > Microsoft +- DOMAIN-SUFFIX,microsoft.com,DIRECT +- DOMAIN-SUFFIX,msecnd.net,DIRECT +- DOMAIN-SUFFIX,office365.com,DIRECT +- DOMAIN-SUFFIX,outlook.com,DIRECT +- DOMAIN-SUFFIX,s-microsoft.com,DIRECT +- DOMAIN-SUFFIX,visualstudio.com,DIRECT +- DOMAIN-SUFFIX,windows.com,DIRECT +- DOMAIN-SUFFIX,windowsupdate.com,DIRECT +- DOMAIN,officecdn-microsoft-com.akamaized.net,DIRECT + +# > Sina +- DOMAIN-SUFFIX,sina.com,DIRECT +- DOMAIN-SUFFIX,weibo.com,DIRECT +- DOMAIN-SUFFIX,weibocdn.com,DIRECT +# > Sohu +- DOMAIN-SUFFIX,sohu.com,DIRECT +- DOMAIN-SUFFIX,sohucs.com,DIRECT +- DOMAIN-SUFFIX,sohu-inc.com,DIRECT +- DOMAIN-SUFFIX,v-56.com,DIRECT +# > Sogo +- DOMAIN-SUFFIX,sogo.com,DIRECT +- DOMAIN-SUFFIX,sogou.com,DIRECT +- DOMAIN-SUFFIX,sogoucdn.com,DIRECT +# > Steam +- DOMAIN-SUFFIX,steampowered.com,DIRECT +- DOMAIN-SUFFIX,steam-chat.com,DIRECT +- DOMAIN-SUFFIX,steamgames.com,DIRECT +- DOMAIN-SUFFIX,steamusercontent.com,DIRECT +- DOMAIN-SUFFIX,steamcontent.com,DIRECT +- DOMAIN-SUFFIX,steamstatic.com,DIRECT +- DOMAIN-SUFFIX,steamcdn-a.akamaihd.net,DIRECT +- DOMAIN-SUFFIX,steamstat.us,DIRECT +# > Tencent +# USER-AGENT,MicroMessenger%20Client,DIRECT +# USER-AGENT,WeChat*,DIRECT +- DOMAIN-SUFFIX,gtimg.com,DIRECT +- DOMAIN-SUFFIX,idqqimg.com,DIRECT +- DOMAIN-SUFFIX,igamecj.com,DIRECT +- DOMAIN-SUFFIX,myapp.com,DIRECT +- DOMAIN-SUFFIX,myqcloud.com,DIRECT +- DOMAIN-SUFFIX,qq.com,Domestic +- DOMAIN-SUFFIX,tencent.com,Domestic +- DOMAIN-SUFFIX,tencent-cloud.net,DIRECT +# > YYeTs +# USER-AGENT,YYeTs*,DIRECT +- DOMAIN-SUFFIX,jstucdn.com,DIRECT +- DOMAIN-SUFFIX,zimuzu.io,DIRECT +- DOMAIN-SUFFIX,zimuzu.tv,DIRECT +- DOMAIN-SUFFIX,zmz2019.com,DIRECT +- DOMAIN-SUFFIX,zmzapi.com,DIRECT +- DOMAIN-SUFFIX,zmzapi.net,DIRECT +- DOMAIN-SUFFIX,zmzfile.com,DIRECT +# > Content Delivery Network +- DOMAIN-SUFFIX,ccgslb.com,DIRECT +- DOMAIN-SUFFIX,ccgslb.net,DIRECT +- DOMAIN-SUFFIX,chinanetcenter.com,DIRECT +- DOMAIN-SUFFIX,meixincdn.com,DIRECT +- DOMAIN-SUFFIX,ourdvs.com,DIRECT +- DOMAIN-SUFFIX,staticdn.net,DIRECT +- DOMAIN-SUFFIX,wangsu.com,DIRECT +# > IP Query +- DOMAIN-SUFFIX,ipip.net,DIRECT +- DOMAIN-SUFFIX,ip.la,DIRECT +- DOMAIN-SUFFIX,ip-cdn.com,DIRECT +- DOMAIN-SUFFIX,ipv6-test.com,DIRECT +- DOMAIN-SUFFIX,test-ipv6.com,DIRECT +- DOMAIN-SUFFIX,whatismyip.com,DIRECT +# > Speed Test +# - DOMAIN-SUFFIX,speedtest.net,DIRECT +- DOMAIN-SUFFIX,netspeedtestmaster.com,DIRECT +- DOMAIN,speedtest.macpaw.com,DIRECT +# > Private Tracker +- DOMAIN-SUFFIX,awesome-hd.me,DIRECT +- DOMAIN-SUFFIX,broadcasthe.net,DIRECT +- DOMAIN-SUFFIX,chdbits.co,DIRECT +- DOMAIN-SUFFIX,classix-unlimited.co.uk,DIRECT +- DOMAIN-SUFFIX,empornium.me,DIRECT +- DOMAIN-SUFFIX,gazellegames.net,DIRECT +- DOMAIN-SUFFIX,hdchina.org,DIRECT +- DOMAIN-SUFFIX,hdsky.me,DIRECT +- DOMAIN-SUFFIX,jpopsuki.eu,DIRECT +- DOMAIN-SUFFIX,keepfrds.com,DIRECT +- DOMAIN-SUFFIX,m-team.cc,DIRECT +- DOMAIN-SUFFIX,nanyangpt.com,DIRECT +- DOMAIN-SUFFIX,ncore.cc,DIRECT +- DOMAIN-SUFFIX,open.cd,DIRECT +- DOMAIN-SUFFIX,ourbits.club,DIRECT +- DOMAIN-SUFFIX,passthepopcorn.me,DIRECT +- DOMAIN-SUFFIX,privatehd.to,DIRECT +- DOMAIN-SUFFIX,redacted.ch,DIRECT +- DOMAIN-SUFFIX,springsunday.net,DIRECT +- DOMAIN-SUFFIX,tjupt.org,DIRECT +- DOMAIN-SUFFIX,totheglory.im,DIRECT +# > Other +- DOMAIN-SUFFIX,cn,DIRECT +- DOMAIN-SUFFIX,360in.com,DIRECT +- DOMAIN-SUFFIX,51ym.me,DIRECT +- DOMAIN-SUFFIX,8686c.com,DIRECT +- DOMAIN-SUFFIX,abchina.com,DIRECT +- DOMAIN-SUFFIX,accuweather.com,DIRECT +- DOMAIN-SUFFIX,aicoinstorge.com,DIRECT +- DOMAIN-SUFFIX,air-matters.com,DIRECT +- DOMAIN-SUFFIX,air-matters.io,DIRECT +- DOMAIN-SUFFIX,aixifan.com,DIRECT +- DOMAIN-SUFFIX,amd.com,DIRECT +- DOMAIN-SUFFIX,b612.net,DIRECT +- DOMAIN-SUFFIX,bdatu.com,DIRECT +- DOMAIN-SUFFIX,beitaichufang.com,DIRECT +- DOMAIN-SUFFIX,bjango.com,DIRECT +- DOMAIN-SUFFIX,booking.com,DIRECT +- DOMAIN-SUFFIX,bstatic.com,DIRECT +- DOMAIN-SUFFIX,cailianpress.com,DIRECT +- DOMAIN-SUFFIX,camera360.com,DIRECT +- DOMAIN-SUFFIX,chinaso.com,DIRECT +- DOMAIN-SUFFIX,chua.pro,DIRECT +- DOMAIN-SUFFIX,chuimg.com,DIRECT +- DOMAIN-SUFFIX,chunyu.mobi,DIRECT +- DOMAIN-SUFFIX,chushou.tv,DIRECT +- DOMAIN-SUFFIX,cmbchina.com,DIRECT +- DOMAIN-SUFFIX,cmbimg.com,DIRECT +- DOMAIN-SUFFIX,ctrip.com,DIRECT +- DOMAIN-SUFFIX,dfcfw.com,DIRECT +- DOMAIN-SUFFIX,docschina.org,DIRECT +- DOMAIN-SUFFIX,douban.com,DIRECT +- DOMAIN-SUFFIX,doubanio.com,DIRECT +- DOMAIN-SUFFIX,douyu.com,DIRECT +- DOMAIN-SUFFIX,dxycdn.com,DIRECT +- DOMAIN-SUFFIX,dytt8.net,DIRECT +- DOMAIN-SUFFIX,eastmoney.com,DIRECT +- DOMAIN-SUFFIX,eudic.net,DIRECT +- DOMAIN-SUFFIX,feng.com,DIRECT +- DOMAIN-SUFFIX,fengkongcloud.com,DIRECT +- DOMAIN-SUFFIX,frdic.com,DIRECT +- DOMAIN-SUFFIX,futu5.com,DIRECT +- DOMAIN-SUFFIX,futunn.com,DIRECT +- DOMAIN-SUFFIX,geilicdn.com,DIRECT +- DOMAIN-SUFFIX,getpricetag.com,DIRECT +- DOMAIN-SUFFIX,gifshow.com,DIRECT +- DOMAIN-SUFFIX,godic.net,DIRECT +- DOMAIN-SUFFIX,hicloud.com,DIRECT +- DOMAIN-SUFFIX,hongxiu.com,DIRECT +- DOMAIN-SUFFIX,hostbuf.com,DIRECT +- DOMAIN-SUFFIX,huxiucdn.com,DIRECT +- DOMAIN-SUFFIX,huya.com,DIRECT +- DOMAIN-SUFFIX,infinitynewtab.com,DIRECT +- DOMAIN-SUFFIX,ithome.com,DIRECT +- DOMAIN-SUFFIX,java.com,DIRECT +- DOMAIN-SUFFIX,jidian.im,DIRECT +- DOMAIN-SUFFIX,kaiyanapp.com,DIRECT +- DOMAIN-SUFFIX,kaspersky-labs.com,DIRECT +- DOMAIN-SUFFIX,keepcdn.com,DIRECT +- DOMAIN-SUFFIX,kkmh.com,DIRECT +- DOMAIN-SUFFIX,licdn.com,DIRECT +- DOMAIN-SUFFIX,linkedin.com,DIRECT +- DOMAIN-SUFFIX,loli.net,DIRECT +- DOMAIN-SUFFIX,luojilab.com,DIRECT +- DOMAIN-SUFFIX,maoyan.com,DIRECT +- DOMAIN-SUFFIX,maoyun.tv,DIRECT +- DOMAIN-SUFFIX,meituan.com,DIRECT +- DOMAIN-SUFFIX,meituan.net,DIRECT +- DOMAIN-SUFFIX,mobike.com,DIRECT +- DOMAIN-SUFFIX,mubu.com,DIRECT +- DOMAIN-SUFFIX,myzaker.com,DIRECT +- DOMAIN-SUFFIX,nim-lang-cn.org,DIRECT +- DOMAIN-SUFFIX,nvidia.com,DIRECT +- DOMAIN-SUFFIX,oracle.com,DIRECT +- DOMAIN-SUFFIX,paypal.com,DIRECT +- DOMAIN-SUFFIX,paypalobjects.com,DIRECT +- DOMAIN-SUFFIX,qdaily.com,DIRECT +- DOMAIN-SUFFIX,qidian.com,DIRECT +- DOMAIN-SUFFIX,qyer.com,DIRECT +- DOMAIN-SUFFIX,qyerstatic.com,DIRECT +- DOMAIN-SUFFIX,raychase.net,DIRECT +- DOMAIN-SUFFIX,ronghub.com,DIRECT +- DOMAIN-SUFFIX,ruguoapp.com,DIRECT +- DOMAIN-SUFFIX,sankuai.com,DIRECT +- DOMAIN-SUFFIX,scomper.me,DIRECT +- DOMAIN-SUFFIX,seafile.com,DIRECT +- DOMAIN-SUFFIX,sm.ms,DIRECT +- DOMAIN-SUFFIX,smzdm.com,DIRECT +- DOMAIN-SUFFIX,snapdrop.net,DIRECT +- DOMAIN-SUFFIX,snwx.com,DIRECT +- DOMAIN-SUFFIX,s-reader.com,DIRECT +- DOMAIN-SUFFIX,sspai.com,DIRECT +- DOMAIN-SUFFIX,takungpao.com,DIRECT +- DOMAIN-SUFFIX,teamviewer.com,DIRECT +- DOMAIN-SUFFIX,tianyancha.com,DIRECT +- DOMAIN-SUFFIX,udacity.com,DIRECT +- DOMAIN-SUFFIX,uning.com,DIRECT +- DOMAIN-SUFFIX,vmware.com,DIRECT +- DOMAIN-SUFFIX,weather.com,DIRECT +- DOMAIN-SUFFIX,weico.cc,DIRECT +- DOMAIN-SUFFIX,weidian.com,DIRECT +- DOMAIN-SUFFIX,xiachufang.com,DIRECT +- DOMAIN-SUFFIX,ximalaya.com,DIRECT +- DOMAIN-SUFFIX,xinhuanet.com,DIRECT +- DOMAIN-SUFFIX,xmcdn.com,DIRECT +- DOMAIN-SUFFIX,yangkeduo.com,DIRECT +- DOMAIN-SUFFIX,zhangzishi.cc,DIRECT +- DOMAIN-SUFFIX,zhihu.com,DIRECT +- DOMAIN-SUFFIX,zhimg.com,DIRECT +- DOMAIN-SUFFIX,zhuihd.com,DIRECT +- DOMAIN,download.jetbrains.com,DIRECT + +# > Apple +- DOMAIN-SUFFIX,aaplimg.com,Apple +- DOMAIN-SUFFIX,apple.co,Apple +- DOMAIN-SUFFIX,apple.com,Apple +- DOMAIN-SUFFIX,appstore.com,Apple +- DOMAIN-SUFFIX,cdn-apple.com,Apple +- DOMAIN-SUFFIX,crashlytics.com,Apple +- DOMAIN-SUFFIX,icloud.com,Apple +- DOMAIN-SUFFIX,icloud-content.com,Apple +- DOMAIN-SUFFIX,me.com,Apple +- DOMAIN-SUFFIX,mzstatic.com,Apple +- DOMAIN,www-cdn.icloud.com.akadns.net,Apple +- IP-CIDR,17.0.0.0/8,Apple + +# Local Area Network +- IP-CIDR,192.168.0.0/16,DIRECT +- IP-CIDR,10.0.0.0/8,DIRECT +- IP-CIDR,172.16.0.0/12,DIRECT +- IP-CIDR,127.0.0.0/8,DIRECT +- IP-CIDR,100.64.0.0/10,DIRECT + + + +- DOMAIN-KEYWORD,amazon,美区影视 +- DOMAIN-KEYWORD,google,google +- DOMAIN-KEYWORD,gmail,google +- DOMAIN-KEYWORD,youtube,google +- DOMAIN-KEYWORD,facebook,Proxy +- DOMAIN-SUFFIX,fb.me,Proxy +- DOMAIN-SUFFIX,fbcdn.net,Proxy +- DOMAIN-KEYWORD,twitter,Proxy +- DOMAIN-KEYWORD,instagram,Proxy +- DOMAIN-KEYWORD,dropbox,Proxy +- DOMAIN-SUFFIX,twimg.com,Proxy +- DOMAIN-KEYWORD,blogspot,Proxy +- DOMAIN-SUFFIX,youtu.be,google +- DOMAIN-KEYWORD,whatsapp,Proxy + +- DOMAIN-SUFFIX,9to5mac.com,Proxy +- DOMAIN-SUFFIX,abpchina.org,Proxy +- DOMAIN-SUFFIX,adblockplus.org,Proxy +- DOMAIN-SUFFIX,adobe.com,Proxy +- DOMAIN-SUFFIX,alfredapp.com,Proxy +- DOMAIN-SUFFIX,amplitude.com,Proxy +- DOMAIN-SUFFIX,ampproject.org,Proxy +- DOMAIN-SUFFIX,android.com,Proxy +- DOMAIN-SUFFIX,angularjs.org,Proxy +- DOMAIN-SUFFIX,aolcdn.com,Proxy +- DOMAIN-SUFFIX,apkpure.com,Proxy +- DOMAIN-SUFFIX,appledaily.com,Proxy +- DOMAIN-SUFFIX,appshopper.com,Proxy +- DOMAIN-SUFFIX,appspot.com,Proxy +- DOMAIN-SUFFIX,arcgis.com,Proxy +- DOMAIN-SUFFIX,archive.org,Proxy +- DOMAIN-SUFFIX,armorgames.com,Proxy +- DOMAIN-SUFFIX,aspnetcdn.com,Proxy +- DOMAIN-SUFFIX,att.com,Proxy +- DOMAIN-SUFFIX,awsstatic.com,Proxy +- DOMAIN-SUFFIX,azureedge.net,Proxy +- DOMAIN-SUFFIX,azurewebsites.net,Proxy +- DOMAIN-SUFFIX,bing.com,Proxy +- DOMAIN-SUFFIX,bintray.com,Proxy +- DOMAIN-SUFFIX,bit.com,Proxy +- DOMAIN-SUFFIX,bit.ly,Proxy +- DOMAIN-SUFFIX,bitbucket.org,Proxy +- DOMAIN-SUFFIX,bjango.com,Proxy +- DOMAIN-SUFFIX,bkrtx.com,Proxy +- DOMAIN-SUFFIX,blog.com,Proxy +- DOMAIN-SUFFIX,blogcdn.com,Proxy +- DOMAIN-SUFFIX,blogger.com,Proxy +- DOMAIN-SUFFIX,blogsmithmedia.com,Proxy +- DOMAIN-SUFFIX,blogspot.com,Proxy +- DOMAIN-SUFFIX,blogspot.hk,Proxy +- DOMAIN-SUFFIX,bloomberg.com,Proxy +- DOMAIN-SUFFIX,box.com,Proxy +- DOMAIN-SUFFIX,box.net,Proxy +- DOMAIN-SUFFIX,cachefly.net,Proxy +- DOMAIN-SUFFIX,chromium.org,Proxy +- DOMAIN-SUFFIX,cl.ly,Proxy +- DOMAIN-SUFFIX,cloudflare.com,Proxy +- DOMAIN-SUFFIX,cloudfront.net,Proxy +- DOMAIN-SUFFIX,cloudmagic.com,Proxy +- DOMAIN-SUFFIX,cmail19.com,Proxy +- DOMAIN-SUFFIX,cnet.com,Proxy +- DOMAIN-SUFFIX,cocoapods.org,Proxy +- DOMAIN-SUFFIX,comodoca.com,Proxy +- DOMAIN-SUFFIX,content.office.net,Proxy +- DOMAIN-SUFFIX,crashlytics.com,Proxy +- DOMAIN-SUFFIX,culturedcode.com,Proxy +- DOMAIN-SUFFIX,d.pr,Proxy +- DOMAIN-SUFFIX,danilo.to,Proxy +- DOMAIN-SUFFIX,dayone.me,Proxy +- DOMAIN-SUFFIX,db.tt,Proxy +- DOMAIN-SUFFIX,deskconnect.com,Proxy +- DOMAIN-SUFFIX,digicert.com,Proxy +- DOMAIN-SUFFIX,disq.us,Proxy +- DOMAIN-SUFFIX,disqus.com,Proxy +- DOMAIN-SUFFIX,disquscdn.com,Proxy +- DOMAIN-SUFFIX,dlercloud.com,Proxy +- DOMAIN-SUFFIX,dnsimple.com,Proxy +- DOMAIN-SUFFIX,docker.com,Proxy +- DOMAIN-SUFFIX,dribbble.com,Proxy +- DOMAIN-SUFFIX,droplr.com,Proxy +- DOMAIN-SUFFIX,duckduckgo.com,Proxy +- DOMAIN-SUFFIX,dueapp.com,Proxy +- DOMAIN-SUFFIX,dytt8.net,Proxy +- DOMAIN-SUFFIX,edgecastcdn.net,Proxy +- DOMAIN-SUFFIX,edgekey.net,Proxy +- DOMAIN-SUFFIX,edgesuite.net,Proxy +- DOMAIN-SUFFIX,engadget.com,Proxy +- DOMAIN-SUFFIX,entrust.net,Proxy +- DOMAIN-SUFFIX,eurekavpt.com,Proxy +- DOMAIN-SUFFIX,evernote.com,Proxy +- DOMAIN-SUFFIX,fabric.io,Proxy +- DOMAIN-SUFFIX,fast.com,Proxy +- DOMAIN-SUFFIX,fastly.net,Proxy +- DOMAIN-SUFFIX,fc2.com,Proxy +- DOMAIN-SUFFIX,feedburner.com,Proxy +- DOMAIN-SUFFIX,feedly.com,Proxy +- DOMAIN-SUFFIX,feedsportal.com,Proxy +- DOMAIN-SUFFIX,fiftythree.com,Proxy +- DOMAIN-SUFFIX,firebaseio.com,Proxy +- DOMAIN-SUFFIX,flexibits.com,Proxy +- DOMAIN-SUFFIX,flickr.com,Proxy +- DOMAIN-SUFFIX,flipboard.com,Proxy +- DOMAIN-SUFFIX,g.co,Proxy +- DOMAIN-SUFFIX,gabia.net,Proxy +- DOMAIN-SUFFIX,geni.us,Proxy +- DOMAIN-SUFFIX,gfx.ms,Proxy +- DOMAIN-SUFFIX,ggpht.com,Proxy +- DOMAIN-SUFFIX,ghostnoteapp.com,Proxy +- DOMAIN-SUFFIX,git.io,Proxy +- DOMAIN-KEYWORD,github,Proxy +- DOMAIN-SUFFIX,g.co,Proxy +- DOMAIN-SUFFIX,gabia.net,Proxy +- DOMAIN-SUFFIX,garena.com,Proxy +- DOMAIN-SUFFIX,gameloft.com,Proxy +- DOMAIN-SUFFIX,geni.us,Proxy +- DOMAIN-SUFFIX,get.how,Proxy +- DOMAIN-SUFFIX,getcloudapp.com,Proxy +- DOMAIN-SUFFIX,getfoxyProxy.org,Proxy +- DOMAIN-SUFFIX,getlantern.org,Proxy +- DOMAIN-SUFFIX,getmdl.io,Proxy +- DOMAIN-SUFFIX,getpricetag.com,Proxy +- DOMAIN-SUFFIX,gfw.press,Proxy +- DOMAIN-SUFFIX,gfx.ms,Proxy +- DOMAIN-SUFFIX,ggpht.com,Proxy +- DOMAIN-SUFFIX,ghostnoteapp.com,Proxy +- DOMAIN-SUFFIX,git.io,Proxy +- DOMAIN-SUFFIX,gitbook.com,Proxy +- DOMAIN-SUFFIX,globalsign.com,Proxy +- DOMAIN-SUFFIX,gmocloud.com,Proxy +- DOMAIN-SUFFIX,gmodules.com,Proxy +- DOMAIN-SUFFIX,go.com,Proxy +- DOMAIN-SUFFIX,go.jp,Proxy +- DOMAIN-SUFFIX,godaddy.com,Proxy +- DOMAIN-SUFFIX,golang.org,Proxy +- DOMAIN-SUFFIX,gongm.in,Proxy +- DOMAIN-SUFFIX,goo.gl,google +- DOMAIN-SUFFIX,goodreaders.com,Proxy +- DOMAIN-SUFFIX,goodreads.com,Proxy +- DOMAIN-SUFFIX,gravatar.com,Proxy +- DOMAIN-SUFFIX,gstatic.cn,Proxy +- DOMAIN-SUFFIX,gstatic.com,Proxy +- DOMAIN-SUFFIX,gunsamerica.com,Proxy +- DOMAIN-SUFFIX,gvt0.com,Proxy +- DOMAIN-SUFFIX,gvt1.com,Proxy +- DOMAIN-SUFFIX,globalsign.com,Proxy +- DOMAIN-SUFFIX,gmodules.com,Proxy +- DOMAIN-SUFFIX,godaddy.com,Proxy +- DOMAIN-SUFFIX,golang.org,Proxy +- DOMAIN-SUFFIX,gongm.in,Proxy +- DOMAIN-SUFFIX,goo.gl,google +- DOMAIN-SUFFIX,goodreaders.com,Proxy +- DOMAIN-SUFFIX,goodreads.com,Proxy +- DOMAIN-SUFFIX,gravatar.com,Proxy +- DOMAIN-SUFFIX,gstatic.com,Proxy +- DOMAIN-SUFFIX,gvt0.com,Proxy +- DOMAIN-SUFFIX,hockeyapp.net,Proxy +- DOMAIN-SUFFIX,hotmail.com,Proxy +- DOMAIN-SUFFIX,icons8.com,Proxy +- DOMAIN-SUFFIX,ift.tt,Proxy +- DOMAIN-SUFFIX,ifttt.com,Proxy +- DOMAIN-SUFFIX,iherb.com,Proxy +- DOMAIN-SUFFIX,imageshack.us,Proxy +- DOMAIN-SUFFIX,img.ly,Proxy +- DOMAIN-SUFFIX,imgur.com,Proxy +- DOMAIN-SUFFIX,imore.com,Proxy +- DOMAIN-SUFFIX,instapaper.com,Proxy +- DOMAIN-SUFFIX,ipn.li,Proxy +- DOMAIN-SUFFIX,is.gd,Proxy +- DOMAIN-SUFFIX,issuu.com,Proxy +- DOMAIN-SUFFIX,itgonglun.com,Proxy +- DOMAIN-SUFFIX,itun.es,Proxy +- DOMAIN-SUFFIX,ixquick.com,Proxy +- DOMAIN-SUFFIX,j.mp,Proxy +- DOMAIN-SUFFIX,js.revsci.net,Proxy +- DOMAIN-SUFFIX,jshint.com,Proxy +- DOMAIN-SUFFIX,jtvnw.net,Proxy +- DOMAIN-SUFFIX,justgetflux.com,Proxy +- DOMAIN-SUFFIX,kat.cr,Proxy +- DOMAIN-SUFFIX,klip.me,Proxy +- DOMAIN-SUFFIX,libsyn.com,Proxy +- DOMAIN-SUFFIX,licdn.com,Proxy +- DOMAIN-SUFFIX,linkedin.com,Proxy +- DOMAIN-SUFFIX,linode.com,Proxy +- DOMAIN-SUFFIX,lithium.com,Proxy +- DOMAIN-SUFFIX,littlehj.com,Proxy +- DOMAIN-SUFFIX,live.com,Proxy +- DOMAIN-SUFFIX,live.net,Proxy +- DOMAIN-SUFFIX,livefilestore.com,Proxy +- DOMAIN-SUFFIX,llnwd.net,Proxy +- DOMAIN-SUFFIX,macid.co,Proxy +- DOMAIN-SUFFIX,macromedia.com,Proxy +- DOMAIN-SUFFIX,macrumors.com,Proxy +- DOMAIN-SUFFIX,mashable.com,Proxy +- DOMAIN-SUFFIX,mathjax.org,Proxy +- DOMAIN-SUFFIX,medium.com,Proxy +- DOMAIN-SUFFIX,mega.co.nz,Proxy +- DOMAIN-SUFFIX,mega.nz,Proxy +- DOMAIN-SUFFIX,megaupload.com,Proxy +- DOMAIN-SUFFIX,microsofttranslator.com,Proxy +- DOMAIN-SUFFIX,mindnode.com,Proxy +- DOMAIN-SUFFIX,mobile01.com,Proxy +- DOMAIN-SUFFIX,modmyi.com,Proxy +- DOMAIN-SUFFIX,msedge.net,Proxy +- DOMAIN-SUFFIX,myfontastic.com,Proxy +- DOMAIN-SUFFIX,name.com,Proxy +- DOMAIN-SUFFIX,nextmedia.com,Proxy +- DOMAIN-SUFFIX,nsstatic.net,Proxy +- DOMAIN-SUFFIX,nssurge.com,Proxy +- DOMAIN-SUFFIX,nyt.com,Proxy +- DOMAIN-SUFFIX,nytimes.com,Proxy +- DOMAIN-SUFFIX,office365.com,Proxy +- DOMAIN-SUFFIX,omnigroup.com,Proxy +- DOMAIN-SUFFIX,onedrive.com,Proxy +- DOMAIN-SUFFIX,onenote.com,Proxy +- DOMAIN-SUFFIX,ooyala.com,Proxy +- DOMAIN-SUFFIX,openvpn.net,Proxy +- DOMAIN-SUFFIX,openwrt.org,Proxy +- DOMAIN-SUFFIX,orkut.com,Proxy +- DOMAIN-SUFFIX,osxdaily.com,Proxy +- DOMAIN-SUFFIX,outlook.com,Proxy +- DOMAIN-SUFFIX,ow.ly,Proxy +- DOMAIN-SUFFIX,paddleapi.com,Proxy +- DOMAIN-SUFFIX,parallels.com,Proxy +- DOMAIN-SUFFIX,parse.com,Proxy +- DOMAIN-SUFFIX,pdfexpert.com,Proxy +- DOMAIN-SUFFIX,periscope.tv,Proxy +- DOMAIN-SUFFIX,pinboard.in,Proxy +- DOMAIN-SUFFIX,pinterest.com,Proxy +- DOMAIN-SUFFIX,pixelmator.com,Proxy +- DOMAIN-SUFFIX,pixiv.net,Proxy +- DOMAIN-SUFFIX,playpcesor.com,Proxy +- DOMAIN-SUFFIX,playstation.com,Proxy +- DOMAIN-SUFFIX,playstation.com.hk,Proxy +- DOMAIN-SUFFIX,playstation.net,Proxy +- DOMAIN-SUFFIX,playstationnetwork.com,Proxy +- DOMAIN-SUFFIX,pushwoosh.com,Proxy +- DOMAIN-SUFFIX,rime.im,Proxy +- DOMAIN-SUFFIX,servebom.com,Proxy +- DOMAIN-SUFFIX,sfx.ms,Proxy +- DOMAIN-SUFFIX,shadowsocks.org,Proxy +- DOMAIN-SUFFIX,sharethis.com,Proxy +- DOMAIN-SUFFIX,shazam.com,Proxy +- DOMAIN-SUFFIX,skype.com,Proxy +- DOMAIN-SUFFIX,smartdnsProxy.com,Proxy +- DOMAIN-SUFFIX,smartmailcloud.com,Proxy +- DOMAIN-SUFFIX,sndcdn.com,Proxy +- DOMAIN-SUFFIX,sony.com,Proxy +- DOMAIN-SUFFIX,soundcloud.com,Proxy +- DOMAIN-SUFFIX,sourceforge.net,Proxy +- DOMAIN-SUFFIX,spotify.com,Proxy +- DOMAIN-SUFFIX,squarespace.com,Proxy +- DOMAIN-SUFFIX,sstatic.net,Proxy +- DOMAIN-SUFFIX,st.luluku.pw,Proxy +- DOMAIN-SUFFIX,stackoverflow.com,Proxy +- DOMAIN-SUFFIX,startpage.com,Proxy +- DOMAIN-SUFFIX,staticflickr.com,Proxy +- DOMAIN-SUFFIX,steamcommunity.com,Proxy +- DOMAIN-SUFFIX,symauth.com,Proxy +- DOMAIN-SUFFIX,symcb.com,Proxy +- DOMAIN-SUFFIX,symcd.com,Proxy +- DOMAIN-SUFFIX,tapbots.com,Proxy +- DOMAIN-SUFFIX,tapbots.net,Proxy +- DOMAIN-SUFFIX,tdesktop.com,Proxy +- DOMAIN-SUFFIX,techcrunch.com,Proxy +- DOMAIN-SUFFIX,techsmith.com,Proxy +- DOMAIN-SUFFIX,thepiratebay.org,Proxy +- DOMAIN-SUFFIX,theverge.com,Proxy +- DOMAIN-SUFFIX,time.com,Proxy +- DOMAIN-SUFFIX,timeinc.net,Proxy +- DOMAIN-SUFFIX,tiny.cc,Proxy +- DOMAIN-SUFFIX,tinypic.com,Proxy +- DOMAIN-SUFFIX,tmblr.co,Proxy +- DOMAIN-SUFFIX,todoist.com,Proxy +- DOMAIN-SUFFIX,trello.com,Proxy +- DOMAIN-SUFFIX,trustasiassl.com,Proxy +- DOMAIN-SUFFIX,tumblr.co,Proxy +- DOMAIN-SUFFIX,tumblr.com,Proxy +- DOMAIN-SUFFIX,tweetdeck.com,Proxy +- DOMAIN-SUFFIX,tweetmarker.net,Proxy +- DOMAIN-SUFFIX,twitch.tv,Proxy +- DOMAIN-SUFFIX,txmblr.com,Proxy +- DOMAIN-SUFFIX,typekit.net,Proxy +- DOMAIN-SUFFIX,ubertags.com,Proxy +- DOMAIN-SUFFIX,ublock.org,Proxy +- DOMAIN-SUFFIX,ubnt.com,Proxy +- DOMAIN-SUFFIX,ulyssesapp.com,Proxy +- DOMAIN-SUFFIX,urchin.com,Proxy +- DOMAIN-SUFFIX,usertrust.com,Proxy +- DOMAIN-SUFFIX,v.gd,Proxy +- DOMAIN-SUFFIX,vimeo.com,Proxy +- DOMAIN-SUFFIX,vimeocdn.com,Proxy +- DOMAIN-SUFFIX,vine.co,Proxy +- DOMAIN-SUFFIX,vivaldi.com,Proxy +- DOMAIN-SUFFIX,vox-cdn.com,Proxy +- DOMAIN-SUFFIX,vsco.co,Proxy +- DOMAIN-SUFFIX,vultr.com,Proxy +- DOMAIN-SUFFIX,w.org,Proxy +- DOMAIN-SUFFIX,w3schools.com,Proxy +- DOMAIN-SUFFIX,webtype.com,Proxy +- DOMAIN-SUFFIX,wikiwand.com,Proxy +- DOMAIN-SUFFIX,wikileaks.org,Proxy +- DOMAIN-SUFFIX,wikimedia.org,Proxy +- DOMAIN-SUFFIX,wikipedia.com,Proxy +- DOMAIN-SUFFIX,wikipedia.org,Proxy +- DOMAIN-SUFFIX,windows.com,Proxy +- DOMAIN-SUFFIX,windows.net,Proxy +- DOMAIN-SUFFIX,wire.com,Proxy +- DOMAIN-SUFFIX,wordpress.com,Proxy +- DOMAIN-SUFFIX,workflowy.com,Proxy +- DOMAIN-SUFFIX,wp.com,Proxy +- DOMAIN-SUFFIX,wsj.com,Proxy +- DOMAIN-SUFFIX,wsj.net,Proxy +- DOMAIN-SUFFIX,xda-developers.com,Proxy +- DOMAIN-SUFFIX,xeeno.com,Proxy +- DOMAIN-SUFFIX,xiti.com,Proxy +- DOMAIN-SUFFIX,yahoo.com,Proxy +- DOMAIN-SUFFIX,yimg.com,Proxy +- DOMAIN-SUFFIX,ying.com,Proxy +- DOMAIN-SUFFIX,yoyo.org,Proxy +- DOMAIN-SUFFIX,ytimg.com,Proxy + +- DOMAIN-SUFFIX,telegra.ph,Proxy +- DOMAIN-SUFFIX,telegram.org,Proxy +- IP-CIDR,91.108.56.0/22,Proxy +- IP-CIDR,91.108.4.0/22,Proxy +- IP-CIDR,91.108.8.0/22,Proxy +- IP-CIDR,109.239.140.0/24,Proxy +- IP-CIDR,149.154.160.0/20,Proxy +- IP-CIDR,149.154.164.0/22,Proxy + +- DOMAIN-SUFFIX,local,DIRECT +- IP-CIDR,127.0.0.0/8,DIRECT +- IP-CIDR,172.16.0.0/12,DIRECT +- IP-CIDR,192.168.0.0/16,DIRECT +- IP-CIDR,10.0.0.0/8,DIRECT +- IP-CIDR,17.0.0.0/8,DIRECT +- IP-CIDR,100.64.0.0/10,DIRECT +- DOMAIN-SUFFIX,vd.l.qq.com,Domestic + +- DOMAIN-SUFFIX,analytics.strava.com,DIRECT + + +- DOMAIN,vd.l.qq.com,DIRECT + +- DOMAIN,analytics.strava.com,DIRECT + + + +- GEOIP,CN,Domestic +- MATCH,Final \ No newline at end of file diff --git a/ini_reader.h b/ini_reader.h new file mode 100644 index 0000000..d050b8b --- /dev/null +++ b/ini_reader.h @@ -0,0 +1,711 @@ +#ifndef INI_READER_H_INCLUDED +#define INI_READER_H_INCLUDED + +#include +#include +#include + +#define MAX_LINE_LENGTH 4096 + +typedef std::map> ini_data_struct; +typedef std::multimap string_multimap; + +class INIReader +{ + /** + * @brief A simple INI reader which utilize map and vector + * to store sections and items, allowing access in logarithmic time. + */ +private: + bool parsed = false; + std::string current_section; + ini_data_struct ini_content; + string_array exclude_sections, include_sections, read_sections; + + std::string cached_section; + string_multimap cached_section_content; + + std::string isolated_items_section; + + bool chkIgnore(std::string section) + { + bool excluded = false, included = false; + if(count(exclude_sections.begin(), exclude_sections.end(), section) > 0) + excluded = true; + if(include_sections.size() != 0) + { + if(count(include_sections.begin(), include_sections.end(), section) > 0) + included = true; + } + else + included = true; + + return excluded || !included; + } +public: + /** + * @brief Set this flag to true to do a UTF8-To-GBK conversion before parsing data. Only useful in Windows. + */ + bool do_utf8_to_gbk = false; + + /** + * @brief Set this flag to true so any line within the section will be stored even it doesn't follow the "name=value" format. + * These lines will store as the name "{NONAME}". + */ + bool store_any_line = false; + + /** + * @brief Save isolated items before any section definitions. + */ + bool store_isolated_line = false; + + /** + * @brief Allow a section title to appear multiple times. + */ + bool allow_dup_section_titles = false; + + /** + * @brief Initialize the reader. + */ + INIReader() + { + parsed = false; + } + + /** + * @brief Parse a file during initialization. + */ + INIReader(std::string filePath) + { + parsed = false; + ParseFile(filePath); + } + + ~INIReader() + { + //nothing to do + } + + /** + * @brief Exclude a section with the given name. + */ + void ExcludeSection(std::string section) + { + exclude_sections.emplace_back(section); + } + + /** + * @brief Include a section with the given name. + */ + void IncludeSection(std::string section) + { + include_sections.emplace_back(section); + } + + /** + * @brief Set isolated items to given section. + */ + void SetIsolatedItemsSection(std::string section) + { + isolated_items_section = section; + } + + /** + * @brief Parse INI content into mapped data structure. + * If exclude sections are set, these sections will not be stored. + * If include sections are set, only these sections will be stored. + */ + int Parse(std::string content) //parse content into mapped data + { + if(!content.size()) //empty content + return -1; + + //remove UTF-8 BOM + removeUTF8BOM(content); + + bool inExcludedSection = false; + std::string strLine, thisSection, curSection, itemName, itemVal; + string_multimap itemGroup, existItemGroup; + std::stringstream strStrm; + unsigned int lineSize = 0, epos = 0; + char delimiter = count(content.begin(), content.end(), '\n') <= 1 ? '\r' : '\n'; + + EraseAll(); //first erase all data + if(do_utf8_to_gbk && is_str_utf8(content)) + content = UTF8ToGBK(content); //do conversion if flag is set + + if(store_isolated_line) + curSection = isolated_items_section; //items before any section define will be store in this section + strStrm< MAX_LINE_LENGTH || strLine[0] == ';' || strLine[0] == '#') //empty lines, lines longer than MAX_LINE_LENGTH and comments are ignored + continue; + if(strLine[lineSize - 1] == '\r') //remove line break + { + strLine.replace(lineSize - 1, 0, ""); + lineSize--; + } + epos = strLine.find("="); + if(epos != strLine.npos) //is an item + { + if(inExcludedSection) //this section is excluded + continue; + if(!curSection.size()) //not in any section + return -1; + itemName = trim(strLine.substr(0, epos)); + itemVal = trim(strLine.substr(epos + 1)); + itemGroup.emplace(itemName, itemVal); //insert to current section + } + else if(strLine[0] == '[' && strLine[lineSize - 1] == ']') //is a section title + { + thisSection = strLine.substr(1, lineSize - 2); //save section title + inExcludedSection = chkIgnore(thisSection); //check if this section is excluded + + if(curSection.size() && itemGroup.size()) //just finished reading a section + { + if(ini_content.count(curSection)) //a section with the same name has been inserted + { + if(allow_dup_section_titles) + { + eraseElements(existItemGroup); + existItemGroup = ini_content.at(curSection); //get the old items + for(auto &x : existItemGroup) + itemGroup.emplace(x); //insert them all into new section + ini_content.erase(curSection); //remove the old section + } + else + return -1; //not allowed, stop + } + ini_content.emplace(curSection, itemGroup); //insert previous section to content map + read_sections.emplace_back(curSection); //add to read sections list + } + eraseElements(itemGroup); //reset section storage + curSection = thisSection; //start a new section + } + else if(store_any_line && !inExcludedSection && curSection.size()) //store a line without name + { + itemGroup.emplace("{NONAME}", strLine); + } + if(include_sections.size() && include_sections == read_sections) //all included sections has been read + break; //exit now + } + if(curSection.size() && itemGroup.size()) //final section + { + if(ini_content.count(curSection)) //a section with the same name has been inserted + { + if(allow_dup_section_titles) + { + eraseElements(existItemGroup); + existItemGroup = ini_content.at(curSection); //get the old items + for(auto &x : existItemGroup) + itemGroup.emplace(x); //insert them all into new section + ini_content.erase(curSection); //remove the old section + } + else + return -1; //not allowed, stop + } + ini_content.emplace(curSection, itemGroup); //insert this section to content map + read_sections.emplace_back(curSection); //add to read sections list + } + parsed = true; + return 0; //all done + } + + /** + * @brief Parse an INI file into mapped data structure. + */ + int ParseFile(std::string filePath) + { + if(!fileExist(filePath)) + return -1; + return Parse(fileGet(filePath, false)); + } + + /** + * @brief Check whether a section exist. + */ + bool SectionExist(std::string section) + { + return ini_content.find(section) != ini_content.end(); + } + + /** + * @brief Count of sections in the whole INI. + */ + unsigned int SectionCount() + { + return ini_content.size(); + } + + /** + * @brief Return all section names inside INI. + */ + string_array GetSections() + { + string_array retData; + + for(auto &x : ini_content) + { + retData.emplace_back(x.first); + } + + return retData; + } + + /** + * @brief Enter a section with the given name. Section name and data will be cached to speed up the following reading process. + */ + int EnterSection(std::string section) + { + if(!SectionExist(section)) + return -1; + current_section = cached_section = section; + cached_section_content = ini_content.at(section); + return 0; + } + + /** + * @brief Set current section. + */ + void SetCurrentSection(std::string section) + { + current_section = section; + } + + /** + * @brief Check whether an item exist in the given section. Return false if the section does not exist. + */ + bool ItemExist(std::string section, std::string itemName) + { + if(!SectionExist(section)) + return false; + + if(section != cached_section) + { + cached_section = section; + cached_section_content= ini_content.at(section); + } + + return cached_section_content.find(itemName) != cached_section_content.end(); + } + + /** + * @brief Check whether an item exist in current section. Return false if the section does not exist. + */ + bool ItemExist(std::string itemName) + { + return current_section.size() ? ItemExist(current_section, itemName) : false; + } + + /** + * @brief Check whether an item with the given name prefix exist in the given section. Return false if the section does not exist. + */ + bool ItemPrefixExist(std::string section, std::string itemName) + { + if(!SectionExist(section)) + return false; + + if(section != cached_section) + { + cached_section = section; + cached_section_content= ini_content.at(section); + } + + for(auto &x : cached_section_content) + { + if(x.first.find(itemName) == 0) + return true; + } + + return false; + } + + /** + * @brief Check whether an item with the given name prefix exist in current section. Return false if the section does not exist. + */ + bool ItemPrefixExist(std::string itemName) + { + return current_section.size() ? ItemPrefixExist(current_section, itemName) : false; + } + + /** + * @brief Count of items in the given section. Return 0 if the section does not exist. + */ + unsigned int ItemCount(std::string section) + { + if(!parsed || !SectionExist(section)) + return 0; + + return ini_content.at(section).size(); + } + + /** + * @brief Erase all data from the data structure and reset parser status. + */ + void EraseAll() + { + eraseElements(ini_content); + parsed = false; + } + + /** + * @brief Retrieve all items in the given section. + */ + int GetItems(std::string section, std::multimap &data) + { + if(!parsed || !SectionExist(section)) + return -1; + + if(cached_section != section) + { + cached_section = section; + cached_section_content = ini_content.at(section); + } + + data = cached_section_content; + return 0; + } + + /** + * @brief Retrieve all items in current section. + */ + int GetItems(string_multimap &data) + { + return current_section.size() ? GetItems(current_section, data) : -1; + } + + /** + * @brief Retrieve item(s) with the same name prefix in the given section. + */ + int GetAll(std::string section, std::string itemName, string_array &results) //retrieve item(s) with the same itemName prefix + { + if(!parsed) + return -1; + + string_multimap mapTemp; + + if(GetItems(section, mapTemp) != 0) + return -1; + + for(auto &x : mapTemp) + { + if(x.first.find(itemName) == 0) + results.emplace_back(x.second); + } + + return 0; + } + + /** + * @brief Retrieve item(s) with the same name prefix in current section. + */ + int GetAll(std::string itemName, string_array &results) + { + return current_section.size() ? GetAll(current_section, itemName, results) : -1; + } + + /** + * @brief Retrieve one item with the exact same name in the given section. + */ + std::string Get(std::string section, std::string itemName) //retrieve one item with the exact same itemName + { + if(!parsed) + return std::string(); + + string_multimap mapTemp; + + if(GetItems(section, mapTemp) != 0) + return std::string(); + + for(auto &x : mapTemp) + { + if(x.first == itemName) + return x.second; + } + + return std::string(); + } + + /** + * @brief Retrieve one item with the exact same name in current section. + */ + std::string Get(std::string itemName) + { + return current_section.size() ? Get(current_section, itemName) : std::string(); + } + + /** + * @brief Retrieve one boolean item value with the exact same name in the given section. + */ + bool GetBool(std::string section, std::string itemName) + { + return Get(section, itemName) == "true"; + } + + /** + * @brief Retrieve one boolean item value with the exact same name in current section. + */ + bool GetBool(std::string itemName) + { + return current_section.size() ? Get(current_section, itemName) == "true" : false; + } + + /** + * @brief Retrieve one integer item value with the exact same name in the given section. + */ + int GetInt(std::string section, std::string itemName) + { + return stoi(Get(section, itemName)); + } + + /** + * @brief Retrieve one integer item value with the exact same name in current section. + */ + int GetInt(std::string itemName) + { + return GetInt(current_section, itemName); + } + + /** + * @brief Retrieve the first item found in the given section. + */ + std::string GetFirst(std::string section, std::string itemName) //return the first item value found in section + { + if(!parsed) + return std::string(); + string_array result; + if(GetAll(section, itemName, result) != -1) + return result[0]; + else + return std::string(); + } + + /** + * @brief Retrieve the first item found in current section. + */ + std::string GetFirst(std::string itemName) + { + return current_section.size() ? GetFirst(current_section, itemName) : std::string(); + } + + /** + * @brief Retrieve a string style array with specific separator and write into integer array. + */ + template void GetIntArray(std::string section, std::string itemName, std::string separator, T &Array) + { + string_array vArray; + unsigned int index, UBound = sizeof(Array) / sizeof(Array[0]); + vArray = split(Get(section, itemName), separator); + for(index = 0; index < vArray.size() && index < UBound; index++) + Array[index] = stoi(vArray[index]); + for(; index < UBound; index++) + Array[index] = 0; + } + + /** + * @brief Retrieve a string style array with specific separator and write into integer array. + */ + template void GetIntArray(std::string itemName, std::string separator, T &Array) + { + if(current_section.size()) + GetIntArray(current_section, itemName, separator, Array); + } + + /** + * @brief Add a std::string value with given values. + */ + int Set(std::string section, std::string itemName, std::string itemVal) + { + std::string value; + + if(!section.size()) + return -1; + + if(!parsed) + parsed = true; + + if(SectionExist(section)) + { + string_multimap &mapTemp = ini_content.at(section); + mapTemp.insert(std::pair(itemName, itemVal)); + } + else + { + string_multimap mapTemp; + mapTemp.insert(std::pair(itemName, itemVal)); + ini_content.insert(std::pair>(section, mapTemp)); + } + + return 0; + } + + /** + * @brief Add a string value with given values. + */ + int Set(std::string itemName, std::string itemVal) + { + if(!current_section.size()) + return -1; + return Set(current_section, itemName, itemVal); + } + + /** + * @brief Add a boolean value with given values. + */ + int SetBool(std::string section, std::string itemName, bool itemVal) + { + return Set(section, itemName, itemVal ? "true" : "false"); + } + + /** + * @brief Add a boolean value with given values. + */ + int SetBool(std::string itemName, bool itemVal) + { + return SetBool(current_section, itemName, itemVal); + } + + /** + * @brief Add a double value with given values. + */ + int SetDouble(std::string section, std::string itemName, double itemVal) + { + return Set(section, itemName, std::__cxx11::to_string(itemVal)); + } + + /** + * @brief Add a double value with given values. + */ + int SetDouble(std::string itemName, double itemVal) + { + return SetDouble(current_section, itemName, itemVal); + } + + /** + * @brief Add a long value with given values. + */ + int SetLong(std::string section, std::string itemName, long itemVal) + { + return Set(section, itemName, std::__cxx11::to_string(itemVal)); + } + + /** + * @brief Add a long value with given values. + */ + int SetLong(std::string itemName, long itemVal) + { + return SetLong(current_section, itemName, itemVal); + } + + /** + * @brief Add an array with the given separator. + */ + template int SetArray(std::string section, std::string itemName, std::string separator, T &Array) + { + std::string data; + for(auto &x : Array) + data += std::__cxx11::to_string(x) + separator; + data = data.substr(0, data.size() - separator.size()); + return Set(section, itemName, data); + } + + /** + * @brief Add an array with the given separator. + */ + template int SetArray(std::string itemName, std::string separator, T &Array) + { + return current_section.size() ? SetArray(current_section, itemName, separator, Array) : -1; + } + + /** + * @brief Erase all items with the given name. + */ + int Erase(std::string section, std::string itemName) + { + int retVal; + if(!SectionExist(section)) + return -1; + + retVal = ini_content.at(section).erase(itemName); + if(retVal && cached_section == section) + { + cached_section_content = ini_content.at(section); + } + return retVal; + } + + /** + * @brief Erase all items with the given name. + */ + int Erase(std::string itemName) + { + return current_section.size() ? Erase(current_section, itemName) : -1; + } + + /** + * @brief Erase the first item with the given name. + */ + int EraseFirst(std::string section, std::string itemName) + { + string_multimap &mapTemp = ini_content.at(section); + string_multimap::iterator iter = mapTemp.find(itemName); + if(iter != mapTemp.end()) + { + mapTemp.erase(iter); + if(cached_section == section) + { + cached_section_content = mapTemp; + } + return 0; + } + else + { + return -1; + } + } + + /** + * @brief Erase the first item with the given name. + */ + int EraseFirst(std::string itemName) + { + return current_section.size() ? EraseFirst(current_section, itemName) : -1; + } + + /** + * @brief Export the whole INI data structure into a string. + */ + std::string ToString() + { + std::string content; + + if(!parsed) + return std::string(); + + for(auto &x : ini_content) + { + content += "[" + x.first + "]\n"; + for(auto &y : x.second) + { + if(y.first != "{NONAME}") + content += y.first + " = "; + content += y.second + "\n"; + } + content += "\n"; + } + + return content; + } + + /** + * @brief Export the whole INI data structure into a file. + */ + int ToFile(std::string filePath) + { + return fileWrite(filePath, ToString(), true); + } +}; + +#endif // INI_READER_H_INCLUDED diff --git a/logger.cpp b/logger.cpp new file mode 100644 index 0000000..b535fe1 --- /dev/null +++ b/logger.cpp @@ -0,0 +1,8 @@ +#include + +#include "logger.h" + +void writeLog(int type, std::string content) +{ + //placeholder +} diff --git a/logger.h b/logger.h new file mode 100644 index 0000000..93e9152 --- /dev/null +++ b/logger.h @@ -0,0 +1,35 @@ +#ifndef LOGGER_H_INCLUDED +#define LOGGER_H_INCLUDED + +#include + +#include "misc.h" + +#define LOG_TYPE_INFO 1 +#define LOG_TYPE_ERROR 2 +#define LOG_TYPE_RAW 3 +#define LOG_TYPE_WARN 4 +#define LOG_TYPE_TCPING 5 +#define LOG_TYPE_FILEDL 6 +#define LOG_TYPE_GEOIP 7 +#define LOG_TYPE_RULES 8 +#define LOG_TYPE_GPING 9 +#define LOG_TYPE_RENDER 10 +#define LOG_TYPE_FILEUL 11 + +extern std::string resultPath, logPath; + +int makeDir(const char *path); +std::string getTime(int type); +void logInit(bool rpcmode); +void resultInit(); +void writeLog(int type, std::string content); +void logEOF(); + +/* +void resultInit(bool export_with_maxspeed); +void writeResult(nodeInfo *node, bool export_with_maxspeed); +void resultEOF(std::string traffic, int worknodes, int totnodes); +void exportResult(std::string outpath, std::string utiljspath, std::string stylepath, bool export_with_maxspeed); +*/ +#endif // LOGGER_H_INCLUDED diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..1cff684 --- /dev/null +++ b/main.cpp @@ -0,0 +1,241 @@ +#include +#include + +#include + +#include "socket.h" +#include "misc.h" +#include "nodeinfo.h" +#include "speedtestutil.h" +#include "nodemanip.h" +#include "ini_reader.h" +#include "webget.h" +#include "webserver.h" +#include "subexport.h" + +//common settings +string_array def_exclude_remarks, def_include_remarks, rulesets; +std::vector ruleset_content_array; +std::string listen_address = "127.0.0.1", default_url; +int listen_port = 25500, max_pending_connections = 10, max_concurrent_threads = 4; +bool api_mode = true, update_ruleset_on_request = false, overwrite_original_rules = true; +extern std::string custom_group; + +//preferences +string_array renames, emojis; +bool add_emoji = false, remove_old_emoji = false; + +//clash custom +std::string clash_rule_base, clash_base_content; +string_array clash_extra_group; + +std::string refreshRulesets() +{ + eraseElements(ruleset_content_array); + string_array vArray; + std::string rule_group, rule_url, proxy = getSystemProxy(); + ruleset_content rc; + for(std::string &x : rulesets) + { + vArray = split(x, ","); + if(vArray.size() != 2) + continue; + rule_group = trim(vArray[0]); + rule_url = trim(vArray[1]); + if(rule_url.find("[]") == 0) + { + std::cerr<<"Adding rule '"< &nodes, std::string &baseConf, std::vector &ruleset_content_array, string_array &extra_proxy_group, bool clashR); + +int main() +{ +#ifdef _WIN32 + WSADATA wsaData; + if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) + { + fprintf(stderr, "WSAStartup failed.\n"); + return 1; + } + SetConsoleOutputCP(65001); +#endif // _WIN32 + + readConf(); + if(!update_ruleset_on_request) + refreshRulesets(); + + append_response("GET", "/refreshrules", "text/plain", [](RESPONSE_CALLBACK_ARGS) -> std::string + { + return refreshRulesets(); + }); + + append_response("GET", "/clash", "text/plain;charset=utf-8", [](RESPONSE_CALLBACK_ARGS) -> std::string + { + readConf(); + std::string url = UrlDecode(getUrlArg(argument, "url")), include = UrlDecode(getUrlArg(argument, "regex")), group = UrlDecode(getUrlArg(argument, "group")); + if(!url.size()) url = default_url; + string_array urls = split(url, "|"); + std::vector nodes; + if(include.size()) + { + eraseElements(def_include_remarks); + def_include_remarks.emplace_back(include); + } + if(group.size()) custom_group = group; + for(std::string &x : urls) + { + std::cerr<<"Fetching node data from url '"< std::string + { + readConf(); + std::string url = UrlDecode(getUrlArg(argument, "url")), include = UrlDecode(getUrlArg(argument, "regex")), group = UrlDecode(getUrlArg(argument, "group")); + if(!url.size()) url = default_url; + string_array urls = split(url, "|"); + std::vector nodes; + if(include.size()) + { + eraseElements(def_include_remarks); + def_include_remarks.emplace_back(include); + } + if(group.size()) custom_group = group; + for(std::string &x : urls) + { + std::cerr<<"Fetching node data from url '"< std::string + { + std::string url = UrlDecode(getUrlArg(argument, "url")); + return webGet(url, ""); + }); + + append_response("GET", "/getlocal", "text/plain;charset=utf-8", [](RESPONSE_CALLBACK_ARGS) -> std::string + { + return fileGet(UrlDecode(getUrlArg(argument, "path"))); + }); + } + + listener_args args = {listen_address, listen_port, 10240, 4}; + std::cout<<"Serving HTTP @ http://"< +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "misc.h" + +#ifdef _WIN32 +//#include +#include +#include +#else +#ifndef __hpux +#include +#endif /* __hpux */ +#ifndef _access +#define _access access +#endif // _access +#include +#endif // _WIN32 + +using namespace std::__cxx11; + +void sleep(int interval) +{ + /* + #ifdef _WIN32 + Sleep(interval); + #else + // Portable sleep for platforms other than Windows. + struct timeval wait = { 0, interval * 1000 }; + select(0, NULL, NULL, NULL, &wait); + #endif + */ + //upgrade to c++11 standard + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); +} + +std::string GBKToUTF8(std::string str_src) +{ +#ifdef _WIN32 + const char* strGBK = str_src.c_str(); + int len = MultiByteToWideChar(CP_ACP, 0, strGBK, -1, NULL, 0); + wchar_t* wstr = new wchar_t[len + 1]; + memset(wstr, 0, len + 1); + MultiByteToWideChar(CP_ACP, 0, strGBK, -1, wstr, len); + len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); + char* str = new char[len + 1]; + memset(str, 0, len + 1); + WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); + std::string strTemp = str; + if(wstr) + delete[] wstr; + if(str) + delete[] str; + return strTemp; +#else + return str_src; +#endif // _WIN32 +} + +std::string UTF8ToGBK(std::string str_src) +{ +#ifdef _WIN32 + const char* strUTF8 = str_src.data(); + int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, NULL, 0); + wchar_t* wszGBK = new wchar_t[len + 1]; + memset(wszGBK, 0, len * 2 + 2); + MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, wszGBK, len); + len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); + char* szGBK = new char[len + 1]; + memset(szGBK, 0, len + 1); + WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); + std::string strTemp(szGBK); + if (wszGBK) + delete[] wszGBK; + if (szGBK) + delete[] szGBK; + return strTemp; +#else + return str_src; +#endif +} + +#ifdef _WIN32 +// std::string to wstring +void StringToWstring(std::wstring& szDst, std::string str) +{ + std::string temp = str; + int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)temp.c_str(), -1, NULL,0); + wchar_t* wszUtf8 = new wchar_t[len + 1]; + memset(wszUtf8, 0, len * 2 + 2); + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)temp.c_str(), -1, (LPWSTR)wszUtf8, len); + szDst = wszUtf8; + std::wstring r = wszUtf8; + delete[] wszUtf8; +} +#endif // _WIN32 + +unsigned char FromHex(unsigned char x) +{ + unsigned char y = '\0'; + if (x >= 'A' && x <= 'Z') + y = x - 'A' + 10; + else if (x >= 'a' && x <= 'z') + y = x - 'a' + 10; + else if (x >= '0' && x <= '9') + y = x - '0'; + else + assert(0); + return y; +} + +std::string UrlDecode(const std::string& str) +{ + std::string strTemp = ""; + size_t length = str.length(); + for (size_t i = 0; i < length; i++) + { + if (str[i] == '+') + strTemp += ' '; + else if (str[i] == '%') + { + assert(i + 2 < length); + unsigned char high = FromHex((unsigned char)str[++i]); + unsigned char low = FromHex((unsigned char)str[++i]); + strTemp += high * 16 + low; + } + else + strTemp += str[i]; + } + return strTemp; +} + +static inline bool is_base64(unsigned char c) +{ + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64_encode(std::string string_to_encode) +{ + char const* bytes_to_encode = string_to_encode.data(); + unsigned int in_len = string_to_encode.size(); + + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) + { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) + { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} + +std::string base64_decode(std::string encoded_string) +{ + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) + { + char_array_4[i++] = encoded_string[in_]; + in_++; + if (i ==4) + { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) + { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) + ret += char_array_3[j]; + } + + return ret; +} + +std::vector split(const std::string &s, const std::string &seperator) +{ + std::vector result; + typedef std::string::size_type string_size; + string_size i = 0; + + while(i != s.size()) + { + int flag = 0; + while(i != s.size() && flag == 0) + { + flag = 1; + for(string_size x = 0; x < seperator.size(); ++x) + if(s[i] == seperator[x]) + { + ++i; + flag = 0; + break; + } + } + + flag = 0; + string_size j = i; + while(j != s.size() && flag == 0) + { + for(string_size x = 0; x < seperator.size(); ++x) + if(s[j] == seperator[x]) + { + flag = 1; + break; + } + if(flag == 0) + ++j; + } + if(i != j) + { + result.push_back(s.substr(i, j-i)); + i = j; + } + } + return result; +} + +std::string getSystemProxy() +{ +#ifdef _WIN32 + HKEY key; + auto ret = RegOpenKeyEx(HKEY_CURRENT_USER, R"(Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings)", 0, KEY_ALL_ACCESS, &key); + if(ret != ERROR_SUCCESS) + { + //std::cout << "open failed: " << ret << std::endl; + return std::string(); + } + + DWORD values_count, max_value_name_len, max_value_len; + ret = RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, + &values_count, &max_value_name_len, &max_value_len, NULL, NULL); + if(ret != ERROR_SUCCESS) + { + //std::cout << "query failed" << std::endl; + return std::string(); + } + + std::vector, DWORD, std::shared_ptr>> values; + for(DWORD i = 0; i < values_count; i++) + { + std::shared_ptr value_name(new char[max_value_name_len + 1], + std::default_delete()); + DWORD value_name_len = max_value_name_len + 1; + DWORD value_type, value_len; + RegEnumValue(key, i, value_name.get(), &value_name_len, NULL, &value_type, NULL, &value_len); + std::shared_ptr value(new BYTE[value_len], + std::default_delete()); + value_name_len = max_value_name_len + 1; + RegEnumValue(key, i, value_name.get(), &value_name_len, NULL, &value_type, value.get(), &value_len); + values.push_back(std::make_tuple(value_name, value_type, value)); + } + + DWORD ProxyEnable = 0; + for (auto x : values) + { + if (strcmp(std::get<0>(x).get(), "ProxyEnable") == 0) + { + ProxyEnable = *(DWORD*)(std::get<2>(x).get()); + } + } + + if (ProxyEnable) + { + for (auto x : values) + { + if (strcmp(std::get<0>(x).get(), "ProxyServer") == 0) + { + //std::cout << "ProxyServer: " << (char*)(std::get<2>(x).get()) << std::endl; + return std::string((char*)(std::get<2>(x).get())); + } + } + } + /* + else { + //std::cout << "Proxy not Enabled" << std::endl; + } + */ + //return 0; + return std::string(); +#else + char* proxy = getenv("ALL_PROXY"); + if(proxy != NULL) + return std::string(proxy); + else + return std::string(); +#endif // _WIN32 +} + +std::string trim(const std::string& str) +{ + std::string::size_type pos = str.find_first_not_of(' '); + if (pos == std::string::npos) + { + return str; + } + std::string::size_type pos2 = str.find_last_not_of(' '); + if (pos2 != std::string::npos) + { + return str.substr(pos, pos2 - pos + 1); + } + return str.substr(pos); +} + +std::string getUrlArg(std::string url, std::string request) +{ + std::smatch result; + if (regex_search(url.cbegin(), url.cend(), result, std::regex(request + "=(.*?)&"))) + { + return result[1]; + } + else if (regex_search(url.cbegin(), url.cend(), result, std::regex(request + "=(.*)"))) + { + return result[1]; + } + else + { + return std::string(); + } +} + +std::string replace_all_distinct(std::string str, std::string old_value, std::string new_value) +{ + for(std::string::size_type pos(0); pos != std::string::npos; pos += new_value.length()) + { + if((pos = str.find(old_value, pos)) != std::string::npos) + str.replace(pos, old_value.length(), new_value); + else + break; + } + return str; +} + +bool regFind(std::string src, std::string target) +{ + std::regex reg(target); + return regex_search(src, reg); +} + +std::string regReplace(std::string src, std::string match, std::string rep) +{ + std::string result = ""; + std::regex reg(match); + regex_replace(back_inserter(result), src.begin(), src.end(), reg, rep); + return result; +} + +bool regMatch(std::string src, std::string match) +{ + std::regex reg(match); + return regex_match(src, reg); +} + +std::string speedCalc(double speed) +{ + if(speed == 0.0) + return std::string("0.00B"); + char str[10]; + std::string retstr; + if(speed >= 1073741824.0) + sprintf(str, "%.2fGB", speed / 1073741824.0); + else if(speed >= 1048576.0) + sprintf(str, "%.2fMB", speed / 1048576.0); + else if(speed >= 1024.0) + sprintf(str, "%.2fKB", speed / 1024.0); + else + sprintf(str, "%.2fB", speed); + retstr = str; + return retstr; +} + +std::string urlsafe_base64_reverse(std::string encoded_string) +{ + return replace_all_distinct(replace_all_distinct(encoded_string, "-", "+"), "_", "/"); +} + +std::string urlsafe_base64_decode(std::string encoded_string) +{ + return base64_decode(urlsafe_base64_reverse(encoded_string)); +} + +std::string getMD5(std::string data) +{ + MD5_CTX ctx; + std::string result; + unsigned int i = 0; + unsigned char digest[16] = {}; + + MD5_Init(&ctx); + MD5_Update(&ctx, data.data(), data.size()); + MD5_Final((unsigned char *)&digest, &ctx); + + char tmp[3] = {}; + for(i = 0; i < 16; i++) + { + snprintf(tmp, 3, "%02x", digest[i]); + result += tmp; + } + + return result; +} + +std::string fileGet(std::string path, bool binary) +{ + std::ifstream infile; + std::stringstream strstrm; + std::ios::openmode mode = binary ? std::ios::binary : std::ios::in; + + infile.open(path, mode); + if(infile) + { + strstrm< regLists = {"^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$", "^((?:[0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::((?:([0-9A-Fa-f]{1,4}:)*[0-9A-Fa-f]{1,4})?)$", "^(::(?:[0-9A-Fa-f]{1,4})(?::[0-9A-Fa-f]{1,4}){5})|((?:[0-9A-Fa-f]{1,4})(?::[0-9A-Fa-f]{1,4}){5}::)$"}; + for(unsigned int i = 0; i < regLists.size(); i++) + { + if(regMatch(address, regLists[i])) + return true; + } + return false; +} + +std::string rand_str(const int len) +{ + std::string retData; + srand(time(NULL)); + int cnt = 0; + while(cnt < len) + { + switch((rand() % 3)) + { + case 1: + retData += ('A' + rand() % 26); + break; + case 2: + retData += ('a' + rand() % 26); + break; + default: + retData += ('0' + rand() % 10); + break; + } + cnt++; + } + return retData; +} + +void urlParse(std::string url, std::string &host, std::string &path, int &port, bool &isTLS) +{ + std::vector args; + + if(regMatch(url, "^https://(.*)")) + isTLS = true; + url = regReplace(url, "^(http|https)://", ""); + if(url.find("/") == url.npos) + { + host = url; + path = "/"; + } + else + { + host = url.substr(0, url.find("/")); + path = url.substr(url.find("/")); + } + if(regFind(host, "\\[(.*)\\]")) //IPv6 + { + args = split(regReplace(host, "\\[(.*)\\](.*)", "$1,$2"), ","); + if(args.size() == 2) //with port + port = stoi(args[1].substr(1)); + host = args[0]; + } + else if(strFind(host, ":")) + { + port = stoi(host.substr(host.rfind(":") + 1)); + host = host.substr(0, host.rfind(":")); + } + if(port == 0) + { + if(isTLS) + port = 443; + else + port = 80; + } +} + +bool is_str_utf8(std::string data) +{ + const char *str = data.c_str(); + unsigned int nBytes = 0; + unsigned char chr = *str; + bool bAllAscii = true; + for (unsigned int i = 0; str[i] != '\0'; ++i) + { + chr = *(str + i); + if (nBytes == 0 && (chr & 0x80) != 0) + { + bAllAscii = false; + } + if (nBytes == 0) + { + if (chr >= 0x80) + { + if (chr >= 0xFC && chr <= 0xFD) + { + nBytes = 6; + } + else if (chr >= 0xF8) + { + nBytes = 5; + } + else if (chr >= 0xF0) + { + nBytes = 4; + } + else if (chr >= 0xE0) + { + nBytes = 3; + } + else if (chr >= 0xC0) + { + nBytes = 2; + } + else + { + return false; + } + nBytes--; + } + } + else + { + if ((chr & 0xC0) != 0x80) + { + return false; + } + nBytes--; + } + } + if (nBytes != 0) + { + return false; + } + if (bAllAscii) + { + return true; + } + return true; +} + +void removeUTF8BOM(std::string &data) +{ + int BOM[3] = {0xef, 0xbb, 0xbf}; + if(data.compare(0, 3, (char*)BOM) == 0) + data = data.substr(3); +} + +int shortAssemble(unsigned short num_a, unsigned short num_b) +{ + return (int)num_b << 16 | num_a; +} + +void shortDisassemble(int source, unsigned short &num_a, unsigned short &num_b) +{ + num_a = (unsigned short)source; + num_b = (unsigned short)(source >> 16); +} + +std::string to_string(YAML::Node &node) +{ + std::stringstream ss; + ss << node; + return ss.str(); +} + +std::string getFormData(std::string &raw_data) +{ + std::stringstream strstrm; + std::string line; + + std::string boundary; + std::string disp; /* content disposition string */ + std::string type; /* content type string */ + std::string file; /* actual file content */ + + + int i = 0; + + strstrm<= bl - 1) + { + // We are at the end of the file + endfile = true; + break; + } + k++; + } + j++; + } + file.append(buffer, j); + j = 0; + }; + break; + } + i++; + } + return file; +} diff --git a/misc.h b/misc.h new file mode 100644 index 0000000..ed7d244 --- /dev/null +++ b/misc.h @@ -0,0 +1,90 @@ +#ifndef MISC_H_INCLUDED +#define MISC_H_INCLUDED + +#include +#include +#include + +#include + +#ifdef _WIN32 +#define PATH_SLASH "\\" +#else +#define PATH_SLASH "//" +#endif // _WIN32 + +typedef std::vector string_array; + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +std::string UrlDecode(const std::string& str); +std::string base64_decode(std::string encoded_string); +std::string base64_encode(std::string string_to_encode); + +std::vector split(const std::string &s, const std::string &seperator); +std::string getUrlArg(std::string url, std::string request); +std::string replace_all_distinct(std::string str, std::string old_value, std::string new_value); +std::string urlsafe_base64_reverse(std::string encoded_string); +std::string urlsafe_base64_decode(std::string encoded_string); +std::string UTF8ToGBK(std::string str_src); +std::string GBKToUTF8(std::string str_src); +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); + +void sleep(int interval); +bool regFind(std::string src, std::string target); +std::string regReplace(std::string src, std::string match, std::string rep); +bool regMatch(std::string src, std::string match); +std::string speedCalc(double speed); +std::string getMD5(std::string data); +bool isIPv4(std::string address); +bool isIPv6(std::string address); +void urlParse(std::string url, std::string &host, std::string &path, int &port, bool &isTLS); +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 fileGet(std::string path, bool binary = true); +int fileWrite(std::string path, std::string content, bool overwrite); +bool fileExist(std::string path); +bool fileCopy(std::string source,std::string dest); +std::string fileToBase64(std::string filepath); +std::string fileGetMD5(std::string filepath); + +static inline bool strFind(std::string str, std::string target) +{ + return str.find(target) != str.npos; +} + +template static inline void eraseElements(T &target) +{ + T().swap(target); +} + +#ifdef _MACOS +namespace std +{ + namespace __cxx11 + { + template std::string to_string(const T& n) + { + std::ostringstream ss; + ss << n ; + return ss.str(); + } + } +} +#endif // _MACOS + +#ifdef _WIN32 +void StringToWstring(std::wstring& szDst, std::string str); +#endif // _WIN32 + +#endif // MISC_H_INCLUDED diff --git a/nodeinfo.h b/nodeinfo.h new file mode 100644 index 0000000..94e13f2 --- /dev/null +++ b/nodeinfo.h @@ -0,0 +1,17 @@ +#ifndef NODEINFO_H_INCLUDED +#define NODEINFO_H_INCLUDED + +#include + +struct nodeInfo +{ + int linkType = -1; + int id = 0; + std::string group; + std::string remarks; + std::string server; + int port = 0; + std::string proxyStr; +}; + +#endif // NODEINFO_H_INCLUDED diff --git a/nodemanip.cpp b/nodemanip.cpp new file mode 100644 index 0000000..fe38918 --- /dev/null +++ b/nodemanip.cpp @@ -0,0 +1,108 @@ +#include +#include +#include + +#include "nodeinfo.h" +#include "printout.h" +#include "logger.h" +#include "webget.h" +#include "speedtestutil.h" + +std::string override_conf_port, custom_group; +int socksport; +bool ss_libev, ssr_libev; + +void copyNodes(std::vector *source, std::vector *dest) +{ + for(auto &x : *source) + { + dest->push_back(x); + } +} + +void addNodes(std::string link, std::vector &allNodes) +{ + int linkType = -1; + std::vector nodes; + nodeInfo node; + std::string strSub, strInput, fileContent, strProxy; + + link = replace_all_distinct(link, "\"", ""); + writeLog(LOG_TYPE_INFO, "Received Link."); + if(strFind(link, "vmess://") || strFind(link, "vmess1://")) + linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; + else if(strFind(link, "ss://")) + linkType = SPEEDTEST_MESSAGE_FOUNDSS; + else if(strFind(link, "ssr://")) + linkType = SPEEDTEST_MESSAGE_FOUNDSSR; + else if(strFind(link, "socks://") || strFind(link, "https://t.me/socks") || strFind(link, "tg://socks")) + linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; + else if(strFind(link, "http://") || strFind(link, "https://") || strFind(link, "surge:///install-config")) + linkType = SPEEDTEST_MESSAGE_FOUNDSUB; + else if(strFind(link, "Netch://")) + linkType = SPEEDTEST_MESSAGE_FOUNDNETCH; + else if(fileExist(link)) + linkType = SPEEDTEST_MESSAGE_FOUNDLOCAL; + + switch(linkType) + { + case SPEEDTEST_MESSAGE_FOUNDSUB: + writeLog(LOG_TYPE_INFO, "Downloading subscription data..."); + if(strFind(link, "surge:///install-config")) //surge config link + link = UrlDecode(getUrlArg(link, "url")); + strSub = webGet(link); + if(strSub.size() == 0) + { + //try to get it again with system proxy + writeLog(LOG_TYPE_WARN, "Cannot download subscription directly. Using system proxy."); + strProxy = getSystemProxy(); + if(strProxy != "") + { + strSub = webGet(link, strProxy); + } + else + writeLog(LOG_TYPE_WARN, "No system proxy is set. Skipping."); + } + if(strSub.size()) + { + writeLog(LOG_TYPE_INFO, "Parsing subscription data..."); + explodeConfContent(strSub, override_conf_port, socksport, ss_libev, ssr_libev, nodes); + copyNodes(&nodes, &allNodes); + } + else + { + writeLog(LOG_TYPE_ERROR, "Cannot download subscription data."); + } + break; + case SPEEDTEST_MESSAGE_FOUNDLOCAL: + writeLog(LOG_TYPE_INFO, "Parsing configuration file data..."); + if(explodeConf(link, override_conf_port, socksport, ss_libev, ssr_libev, nodes) == SPEEDTEST_ERROR_UNRECOGFILE) + { + writeLog(LOG_TYPE_ERROR, "Invalid configuration file!"); + } + else + { + copyNodes(&nodes, &allNodes); + } + break; + default: + if(linkType > 0) + { + explode(link, ss_libev, ssr_libev, override_conf_port, socksport, node); + if(custom_group.size() != 0) + node.group = custom_group; + if(node.server == "") + { + writeLog(LOG_TYPE_ERROR, "No valid link found."); + } + else + { + allNodes.push_back(node); + } + } + else + { + writeLog(LOG_TYPE_ERROR, "No valid link found."); + } + } +} diff --git a/nodemanip.h b/nodemanip.h new file mode 100644 index 0000000..b69398d --- /dev/null +++ b/nodemanip.h @@ -0,0 +1,11 @@ +#ifndef NODEMANIP_H_INCLUDED +#define NODEMANIP_H_INCLUDED + +#include +#include + +#include "nodeinfo.h" + +void addNodes(std::string link, std::vector &allNodes); + +#endif // NODEMANIP_H_INCLUDED diff --git a/pref.ini b/pref.ini new file mode 100644 index 0000000..83b239c --- /dev/null +++ b/pref.ini @@ -0,0 +1,139 @@ +[common] +;Default URLs, used when no URL is provided in request, use "|" to separate multiple subscription links, supports local files/URL +default_url= + +;Exclude nodes which remarks match the following patterns. Supports regular expression. +exclude_remarks=(剩余流量|到期时间|过期时间|官网地址|产品名称) +;exclude_remarks=(other rule) + +;Only include nodes which remarks match the following patterns. Supports regular expression. +;include_remarks=V3.*港 + +;Clash config base used by the generator, supports local files/URL +clash_rule_base=simple_base.yml + +;Rename remarks with the following patterns. Supports regular expression. +;Format: Search_Pattern@Replace_Pattern +;rename_node=IPLC@专线 +;rename_node=RELAY@中转 +;rename_node=BGP-@ +;rename_node=\((.*?) 倍率\)@x$1 +;rename_node=\((.*?)\)$@ x$1 + +[emojis] +add_emoji=true +remove_old_emoji=true + +;Rule to add emojis. Supports regular expression. +;Format: Remark_Search_Pattern,emoji + +rule=(流量|时间|应急),🏳️‍🌈 +rule=阿根廷,🇦🇷 +rule=(奥地利|维也纳),🇦🇹 +rule=(澳大利亚|悉尼),🇦🇺 +rule=(巴西|圣保罗),🇧🇷 +rule=(加拿大|蒙特利尔|温哥华),🇨🇦 +rule=(瑞士|苏黎世),🇨🇭 +rule=(中国|江苏|北京|上海|广州|深圳|杭州|徐州|青岛|宁波|镇江),🇨🇳 +rule=(德|德国|法兰克福),🇩🇪 +rule=(芬兰|赫尔辛基),🇫🇮 +rule=(法国|巴黎),🇫🇷 +rule=(英国|伦敦),🇬🇧 +rule=(港|香港|深港|沪港),🇭🇰 +rule=(印尼|印度尼西亚|雅加达),🇮🇩 +rule=(爱尔兰|都柏林),🇮🇪 +rule=(印度|孟买),🇮🇳 +rule=(意大利|米兰),🇮🇹 +rule=(日|日本|东京|大阪|埼玉|沪日),🇯🇵 +rule=朝鲜,🇰🇵 +rule=(韩国|首尔),🇰🇷 +rule=澳门,🇲🇴 +rule=马来西亚,🇲🇾 +rule=(荷兰|阿姆斯特丹),🇳🇱 +rule=菲律宾,🇵🇭 +rule=罗马尼亚,🇷🇴 +rule=(俄罗斯|伯力|莫斯科|圣彼得堡|西伯利亚|新西伯利亚),🇷🇺 +rule=(新|新加坡|狮城),🇸🇬 +rule=(泰国|曼谷),🇹🇭 +rule=(土耳其|伊斯坦布尔),🇹🇷 +rule=(台|台湾|台北|台中|新北|彰化),🇹🇼 +rule=(美|美国|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥|沪美),🇺🇲 +rule=越南,🇻🇳 +rule=南非,🇿🇦 + +[ruleset] +;Enable generating rules with rulesets +enabled=true + +;Overwrite the existing rules in rule_base +overwrite_original_rules=false + +;Perform a ruleset update on request +update_ruleset_on_request=false + +;Ruleset addresses, supports local files/URL +;Format: Group name,URL +; Group name,[]Rule + +surge_ruleset=DIRECT,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Unbreak.list +surge_ruleset=Advertising,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Advertising.list +surge_ruleset=Hijacking,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Hijacking.list +surge_ruleset=YouTube,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Media/YouTube.list +surge_ruleset=Netflix,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Media/Netflix.list +;surge_ruleset=HBO,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Media/HBO.list +;surge_ruleset=Fox,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Media/Fox.list +surge_ruleset=GlobalMedia,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/GlobalMedia.list +surge_ruleset=HKMTMedia,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/HKMTMedia.list +surge_ruleset=Telegram,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Telegram.list +surge_ruleset=PROXY,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Global.list +surge_ruleset=Apple,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/Apple.list +surge_ruleset=DIRECT,https://raw.githubusercontent.com/ConnersHua/Profiles/master/Surge/Ruleset/China.list +surge_ruleset=Final,[]MATCH + +[clash_proxy_group] +;Generate Clash Proxy Group with the following patterns. Node filterting rule supports regular expression. +;Format: Group_Name`select`Rule_1`Rule_2`... +; Group_Name`url-test|fallback|load-balance`Rule_1`Rule_2`...`test_url`interval +;Rule with "[]" prefix will be added directly. + +;custom_proxy_group=UrlTest`url-test`.*`http://www.gstatic.com/generate_204`300 +;custom_proxy_group=FallBack`fallback`.*`http://www.gstatic.com/generate_204`300 +;custom_proxy_group=LoadBalance`load-balance`.*`http://www.gstatic.com/generate_204`300 + +;for forcerule.yml +;custom_proxy_group=Proxy`select`.* +;custom_proxy_group=google`select`.* +;custom_proxy_group=netflix`select`.* +;custom_proxy_group=动画疯`select`(深台|彰化|新北|台) +;custom_proxy_group=fox+`select`(HGC|HKBN|PCCW|HKT|深台|彰化|新北|台|新加坡|sg|hk|tw) +;custom_proxy_group=美区影视`select`(美|美国) +;custom_proxy_group=Global_media`select`.* +;custom_proxy_group=Domestic`select`[]DIRECT`[]Proxy +;custom_proxy_group=Apple`select`[]DIRECT`[]Proxy +;custom_proxy_group=Final`select`[]Proxy`[]DIRECT +;custom_proxy_group=屏蔽广告`select`[]REJECT`[]DIRECT +;custom_proxy_group=UnblockNeteaseMusic`select`云音乐解锁`[]DIRECT +;custom_proxy_group=Telegram`select`新加坡`[]Proxy + +;for DivineEngine_Profiles +custom_proxy_group=PROXY`select`.* +custom_proxy_group=YouTube`select`.* +custom_proxy_group=Netflix`select`.* +custom_proxy_group=Advertising`select`[]REJECT`[]DIRECT`[]PROXY +custom_proxy_group=Hijacking`select`[]REJECT`[]DIRECT`[]PROXY +custom_proxy_group=GlobalMedia`select`.* +custom_proxy_group=HKMTMedia`select`(HGC|HKBN|PCCW|HKT|深台|彰化|新北|台|新加坡|sg|hk|tw) +custom_proxy_group=Telegram`select`新加坡`[]PROXY +custom_proxy_group=Apple`select`[]DIRECT`[]PROXY +custom_proxy_group=Final`select`[]PROXY`[]DIRECT + +[server] +;Address to bind on for Web Server +listen=0.0.0.0 + +;Port to bind on for Web Server +port=25500 + +[advanced] +max_pending_connections=10 +max_concurrent_threads=4 diff --git a/printout.h b/printout.h new file mode 100644 index 0000000..3e0e679 --- /dev/null +++ b/printout.h @@ -0,0 +1,71 @@ +#ifndef PRINTOUT_H_INCLUDED +#define PRINTOUT_H_INCLUDED + +#include +#include +#include + +#include "misc.h" +#include "nodeinfo.h" + +#define SPEEDTEST_ERROR_NONE 0 +#define SPEEDTEST_ERROR_UNDEFINED 100 +#define SPEEDTEST_ERROR_WSAERR 99 +#define SPEEDTEST_ERROR_SOCKETERR 98 +#define SPEEDTEST_ERROR_NORECOGLINK 97 +#define SPEEDTEST_ERROR_NOCONNECTION 96 +#define SPEEDTEST_ERROR_INVALIDSUB 95 +#define SPEEDTEST_ERROR_NONODES 94 +#define SPEEDTEST_ERROR_NORESOLVE 93 +#define SPEEDTEST_ERROR_RETEST 92 +#define SPEEDTEST_ERROR_NOSPEED 91 +#define SPEEDTEST_ERROR_UNRECOGFILE 90 +#define SPEEDTEST_ERROR_SUBFETCHERR 89 +#define SPEEDTEST_ERROR_GEOIPERR 88 + +#define SPEEDTEST_MESSAGE_WELCOME 0 +#define SPEEDTEST_MESSAGE_FOUNDVMESS 1 +#define SPEEDTEST_MESSAGE_FOUNDSS 2 +#define SPEEDTEST_MESSAGE_FOUNDSSR 3 +#define SPEEDTEST_MESSAGE_FOUNDSUB 4 +#define SPEEDTEST_MESSAGE_GOTSERVER 5 +#define SPEEDTEST_MESSAGE_STARTPING 6 +#define SPEEDTEST_MESSAGE_GOTPING 7 +#define SPEEDTEST_MESSAGE_STARTSPEED 8 +#define SPEEDTEST_MESSAGE_GOTSPEED 9 +#define SPEEDTEST_MESSAGE_GOTRESULT 10 +#define SPEEDTEST_MESSAGE_TRAFFIC 11 +#define SPEEDTEST_MESSAGE_PICSAVING 12 +#define SPEEDTEST_MESSAGE_PICSAVED 13 +#define SPEEDTEST_MESSAGE_GROUP 14 +#define SPEEDTEST_MESSAGE_FETCHSUB 15 +#define SPEEDTEST_MESSAGE_BEGIN 16 +#define SPEEDTEST_MESSAGE_FOUNDLOCAL 17 +#define SPEEDTEST_MESSAGE_PARSING 18 +#define SPEEDTEST_MESSAGE_FOUNDUPD 19 +#define SPEEDTEST_MESSAGE_PICDATA 20 +#define SPEEDTEST_MESSAGE_STARTGPING 21 +#define SPEEDTEST_MESSAGE_GOTGPING 22 +#define SPEEDTEST_MESSAGE_FOUNDSOCKS 23 +#define SPEEDTEST_MESSAGE_STARTGEOIP 24 +#define SPEEDTEST_MESSAGE_GOTGEOIP 25 +#define SPEEDTEST_MESSAGE_FOUNDSSCONF 26 +#define SPEEDTEST_MESSAGE_MULTILINK 27 +#define SPEEDTEST_MESSAGE_PICSAVINGMULTI 28 +#define SPEEDTEST_MESSAGE_PICSAVEDMULTI 29 +#define SPEEDTEST_MESSAGE_STARTUPD 30 +#define SPEEDTEST_MESSAGE_GOTUPD 31 +#define SPEEDTEST_MESSAGE_FOUNDSSTAP 32 +#define SPEEDTEST_MESSAGE_FOUNDNETCH 33 +#define SPEEDTEST_MESSAGE_EOF 49 + +#define SS_DEFAULT_GROUP "SSProvider" +#define SSR_DEFAULT_GROUP "SSRProvider" +#define V2RAY_DEFAULT_GROUP "V2RayProvider" +#define SOCKS_DEFAULT_GROUP "SocksProvider" + +void printMsg(int index, nodeInfo *node, bool rpcmode); +void printMsgWithDict(int index, bool rpcmode, std::vector dict, std::vector trans); +void printMsgDirect(int index, bool rpcmode); + +#endif // PRINTOUT_H_INCLUDED diff --git a/rapidjson_extra.cpp b/rapidjson_extra.cpp new file mode 100644 index 0000000..e737067 --- /dev/null +++ b/rapidjson_extra.cpp @@ -0,0 +1,56 @@ +#include + +#include "rapidjson_extra.h" + +void operator >> (const rapidjson::Value& value, std::string& i) +{ + if(value.IsNull()) + i = std::string(); + else if(value.IsInt64()) + i = std::to_string(value.GetInt64()); + else if(value.IsDouble()) + i = std::to_string(value.GetDouble()); + else if(value.IsString()) + i = std::string(value.GetString()); + else if(value.IsBool()) + i = value.GetBool() ? "true" : "false"; + else + i = std::string(); +} + +void operator >> (const rapidjson::Value& value, int& i) +{ + if(value.IsNull()) + i = 0; + else if(value.IsInt()) + i = value.GetInt(); + else if(value.IsString()) + i = std::stoi(value.GetString()); + else if(value.IsBool()) + i = value.GetBool() ? 1 : 0; + else + i = 0; +} + +std::string GetMember(const rapidjson::Value& value, std::string member) +{ + std::string retStr; + if(value.HasMember(member.data())) + value[member.data()] >> retStr; + return retStr; +} + +void GetMember(const rapidjson::Value& value, std::string member, std::string* target) +{ + std::string retStr = GetMember(value, member); + if(retStr.size()) + target->assign(retStr); +} + +std::string SerializeObject(const rapidjson::Value& value) +{ + rapidjson::StringBuffer sb; + rapidjson::Writer writer_json(sb); + value.Accept(writer_json); + return sb.GetString(); +} diff --git a/rapidjson_extra.h b/rapidjson_extra.h new file mode 100644 index 0000000..6791251 --- /dev/null +++ b/rapidjson_extra.h @@ -0,0 +1,13 @@ +#ifndef RAPIDJSON_EXTRA_H_INCLUDED +#define RAPIDJSON_EXTRA_H_INCLUDED + +#include +#include + +void operator >> (const rapidjson::Value& value, std::string& i); +void operator >> (const rapidjson::Value& value, int& i); +std::string GetMember(const rapidjson::Value& value, std::string member); +void GetMember(const rapidjson::Value& value, std::string member, std::string* target); +std::string SerializeObject(const rapidjson::Value& value); + +#endif // RAPIDJSON_EXTRA_H_INCLUDED diff --git a/simple_base.yml b/simple_base.yml new file mode 100644 index 0000000..6e06fde --- /dev/null +++ b/simple_base.yml @@ -0,0 +1,15 @@ +port: 7890 +socks-port: 7891 +allow-lan: true +mode: Rule +log-level: info +external-controller: 127.0.0.1:9090 +dns: + enable: false + listen: 0.0.0.0:53 + ipv6: false + enhanced-mode: fake-ip + nameserver: + - 119.29.29.29 + - 114.114.114.114 + - 223.5.5.5 \ No newline at end of file diff --git a/socket.h b/socket.h new file mode 100644 index 0000000..7b25526 --- /dev/null +++ b/socket.h @@ -0,0 +1,56 @@ +#ifndef SOCKET_H_INCLUDED +#define SOCKET_H_INCLUDED + +#include + +#ifdef _WIN32 +#ifndef WINVER +#define WINVER 0x0501 +#endif // WINVER +#include +#include +#else +//translate windows functions to linux functions +#include +#define SOCKET int +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR (-1) +#define closesocket close +#define SOCKADDR_IN sockaddr_in +#define ZeroMemory(d,l) memset((d), 0, (l)) +#define ioctlsocket ioctl +#ifndef SA_INTERRUPT +#define SA_INTERRUPT 0 //ignore this setting +#endif +#ifndef __hpux +#include +#endif /* __hpux */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +typedef sockaddr *LPSOCKADDR; +#endif // _WIN32 + +#define BUF_SIZE 8192 + +int getNetworkType(std::string addr); +int Send(SOCKET sHost, const char* data, int len, int flags); +int Recv(SOCKET sHost, char* data, int len, int flags); +int socks5_do_auth_userpass(SOCKET sHost, std::string user, std::string pass); +int setTimeout(SOCKET s, int timeout); +int startConnect(SOCKET sHost, std::string addr, int port); +int simpleSend(std::string addr, int port, std::string data); +int send_simple(SOCKET sHost, std::string data); +std::string hostnameToIPAddr(std::string host); +int connectSocks5(SOCKET sHost, std::string username, std::string password); +int connectThruSocks(SOCKET sHost, std::string host, int port); +int connectThruHTTP(SOCKET sHost, std::string username, std::string password, std::string dsthost, int dstport); +int checkPort(int startport); + +#endif // SOCKET_H_INCLUDED diff --git a/speedtestutil.cpp b/speedtestutil.cpp new file mode 100644 index 0000000..ba65cc5 --- /dev/null +++ b/speedtestutil.cpp @@ -0,0 +1,1558 @@ +#include +#include + +#include + +#include "misc.h" +#include "printout.h" +#include "logger.h" +#include "speedtestutil.h" +#include "webget.h" +#include "rapidjson_extra.h" +#include "ini_reader.h" + +using namespace std::__cxx11; +using namespace rapidjson; +using namespace YAML; + +string_array exclude_remarks; +string_array include_remarks; + +std::string base_ss_win = "{\"version\":\"4.1.6\",\"configs\":[?config?],\"strategy\":null,\"index\":0,\"global\":false,\"enabled\":false,\"shareOverLan\":true,\"isDefault\":false,\"localPort\":?localport?,\"portableMode\":true,\"pacUrl\":null,\"useOnlinePac\":false,\"secureLocalPac\":true,\"availabilityStatistics\":false,\"autoCheckUpdate\":true,\"checkPreRelease\":false,\"isVerboseLogging\":false,\"logViewer\":{\"topMost\":false,\"wrapText\":false,\"toolbarShown\":false,\"Font\":\"Consolas, 8pt\",\"BackgroundColor\":\"Black\",\"TextColor\":\"White\"},\"proxy\":{\"useProxy\":false,\"proxyType\":0,\"proxyServer\":\"\",\"proxyPort\":0,\"proxyTimeout\":3,\"useAuth\":false,\"authUser\":\"\",\"authPwd\":\"\"},\"hotkey\":{\"SwitchSystemProxy\":\"\",\"SwitchSystemProxyMode\":\"\",\"SwitchAllowLan\":\"\",\"ShowLogs\":\"\",\"ServerMoveUp\":\"\",\"ServerMoveDown\":\"\",\"RegHotkeysAtStartup\":false}}"; +std::string config_ss_win = "{\"server\":\"?server?\",\"server_port\":?port?,\"password\":\"?password?\",\"method\":\"?method?\",\"plugin\":\"?plugin?\",\"plugin_opts\":\"?plugin_opts?\",\"plugin_args\":\"\",\"remarks\":\"?remarks?\",\"timeout\":5}"; +std::string config_ss_libev = "{\"server\":\"?server?\",\"server_port\":?port?,\"password\":\"?password?\",\"method\":\"?method?\",\"plugin\":\"?plugin?\",\"plugin_opts\":\"?plugin_opts?\",\"plugin_args\":\"\",\"local_address\":\"127.0.0.1\",\"local_port\":?localport?}"; +std::string base_ssr_win = "{\"configs\":[?config?],\"index\":0,\"random\":true,\"sysProxyMode\":1,\"shareOverLan\":false,\"localPort\":?localport?,\"localAuthPassword\":null,\"localDnsServer\":\"\",\"dnsServer\":\"\",\"reconnectTimes\":2,\"balanceAlgorithm\":\"LowException\",\"randomInGroup\":false,\"TTL\":0,\"connectTimeout\":5,\"proxyRuleMode\":2,\"proxyEnable\":false,\"pacDirectGoProxy\":false,\"proxyType\":0,\"proxyHost\":null,\"proxyPort\":0,\"proxyAuthUser\":null,\"proxyAuthPass\":null,\"proxyUserAgent\":null,\"authUser\":null,\"authPass\":null,\"autoBan\":false,\"checkSwitchAutoCloseAll\":false,\"logEnable\":false,\"sameHostForSameTarget\":false,\"keepVisitTime\":180,\"isHideTips\":false,\"nodeFeedAutoUpdate\":true,\"serverSubscribes\":[],\"token\":{},\"portMap\":{}}"; +std::string config_ssr_win = "{\"remarks\":\"?remarks?\",\"id\":\"18C4949EBCFE46687AE4A7645725D35F\",\"server\":\"?server?\",\"server_port\":?port?,\"server_udp_port\":0,\"password\":\"?password?\",\"method\":\"?method?\",\"protocol\":\"?protocol?\",\"protocolparam\":\"?protoparam?\",\"obfs\":\"?obfs?\",\"obfsparam\":\"?obfsparam?\",\"remarks_base64\":\"?remarks_base64?\",\"group\":\"?group?\",\"enable\":true,\"udp_over_tcp\":false}"; +std::string config_ssr_libev = "{\"server\":\"?server?\",\"server_port\":?port?,\"protocol\":\"?protocol?\",\"method\":\"?method?\",\"obfs\":\"?obfs?\",\"password\":\"?password?\",\"obfs_param\":\"?obfsparam?\",\"protocol_param\":\"?protoparam?\",\"local_address\":\"127.0.0.1\",\"local_port\":?localport?}"; +std::string base_vmess = "{\"inbounds\":[{\"port\":?localport?,\"listen\":\"127.0.0.1\",\"protocol\":\"socks\"}],\"outbounds\":[{\"tag\":\"proxy\",\"protocol\":\"vmess\",\"settings\":{\"vnext\":[{\"address\":\"?add?\",\"port\":?port?,\"users\":[{\"id\":\"?id?\",\"alterId\":?aid?,\"email\":\"t@t.tt\",\"security\":\"?cipher?\"}]}]},\"streamSettings\":{\"network\":\"?net?\",\"security\":\"?tls?\",\"tlsSettings\":?tlsset?,\"tcpSettings\":?tcpset?,\"wsSettings\":?wsset?},\"mux\":{\"enabled\":true}}],\"routing\":{\"domainStrategy\":\"IPIfNonMatch\"}}"; +std::string wsset_vmess = "{\"connectionReuse\":true,\"path\":\"?path?\",\"headers\":{\"Host\":\"?host?\"}}"; +std::string tcpset_vmess = "{\"connectionReuse\":true,\"header\":{\"type\":\"?type?\",\"request\":{\"version\":\"1.1\",\"method\":\"GET\",\"path\":[\"?path?\"],\"headers\":{\"Host\":[\"?host?\"],\"User-Agent\":[\"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36\",\"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46\"],\"Accept-Encoding\":[\"gzip, deflate\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}}}"; +std::string tlsset_vmess = "{\"serverName\":\"?serverName?\",\"allowInsecure\":false,\"allowInsecureCiphers\":false}"; + +std::vector ss_ciphers = {"rc4-md5","aes-128-gcm","aes-192-gcm","aes-256-gcm","aes-128-cfb","aes-192-cfb","aes-256-cfb","aes-128-ctr","aes-192-ctr","aes-256-ctr","camellia-128-cfb","camellia-192-cfb","camellia-256-cfb","bf-cfb","chacha20-ietf-poly1305","xchacha20-ietf-poly1305","salsa20","chacha20","chacha20-ietf"}; + +std::map parsedMD5; +std::string modSSMD5 = "f7653207090ce3389115e9c88541afe0"; + +//remake from speedtestutil + +template void operator >> (const YAML::Node& node, T& i) +{ + i = node.as(); +}; +/* +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 base = base_vmess; + std::string wsset = wsset_vmess; + std::string tcpset = tcpset_vmess; + std::string tlsset = tlsset_vmess; + base = replace_all_distinct(base, "?localport?", to_string(local_port)); + base = replace_all_distinct(base, "?add?", add); + base = replace_all_distinct(base, "?port?", port); + base = replace_all_distinct(base, "?id?", id); + base = replace_all_distinct(base, "?aid?", aid); + base = replace_all_distinct(base, "?net?", net); + base = replace_all_distinct(base, "?cipher?", cipher); + if(net == "ws") + { + wsset = replace_all_distinct(wsset, "?host?", host == "" ? add : host); + wsset = replace_all_distinct(wsset, "?path?", path == "" ? "/" : path); + base = replace_all_distinct(base, "?wsset?", wsset); + } + if(type == "http") + { + tcpset = replace_all_distinct(tcpset, "?host?", host == "" ? add : host); + tcpset = replace_all_distinct(tcpset, "?type?", type); + tcpset = replace_all_distinct(tcpset, "?path?", path == "" ? "/" : path); + base = replace_all_distinct(base, "?tcpset?", tcpset); + } + if(host == "" && !isIPv4(add) && !isIPv6(add)) + host = add; + if(host != "") + { + tlsset = replace_all_distinct(tlsset, "?serverName?", host); + base = replace_all_distinct(base, "?tlsset?", tlsset); + } + + base = replace_all_distinct(base, "?tls?", tls); + base = replace_all_distinct(base, "?tcpset?", "null"); + base = replace_all_distinct(base, "?wsset?", "null"); + base = replace_all_distinct(base, "?tlsset?", "null"); + + return base; +} + +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 base = base_ssr_win; + std::string config = config_ssr_win; + std::string config_libev = config_ssr_libev; + if(libev == true) + config = config_libev; + if(isIPv6(server)) + server = "[" + server + "]"; + config = replace_all_distinct(config, "?group?", group); + config = replace_all_distinct(config, "?remarks?", remarks); + config = replace_all_distinct(config, "?remarks_base64?", remarks_base64); + config = replace_all_distinct(config, "?server?", server); + config = replace_all_distinct(config, "?port?", port); + config = replace_all_distinct(config, "?protocol?", protocol); + config = replace_all_distinct(config, "?method?", method); + config = replace_all_distinct(config, "?obfs?", obfs); + config = replace_all_distinct(config, "?password?", password); + config = replace_all_distinct(config, "?obfsparam?", obfsparam); + config = replace_all_distinct(config, "?protoparam?", protoparam); + if(libev == true) + base = config; + else + base = replace_all_distinct(base, "?config?", config); + base = replace_all_distinct(base, "?localport?", to_string(local_port)); + + return base; +} + +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 base = base_ss_win; + std::string config = config_ss_win; + std::string config_libev = config_ss_libev; + if(plugin == "obfs-local") + plugin = "simple-obfs"; + if(libev == true) + config = config_libev; + if(isIPv6(server)) + server = "[" + server + "]"; + config = replace_all_distinct(config, "?server?", server); + config = replace_all_distinct(config, "?port?", port); + config = replace_all_distinct(config, "?password?", password); + config = replace_all_distinct(config, "?method?", method); + config = replace_all_distinct(config, "?plugin?", plugin); + config = replace_all_distinct(config, "?plugin_opts?", pluginopts); + config = replace_all_distinct(config, "?remarks?", remarks); + if(libev == true) + base = config; + else + base = replace_all_distinct(base, "?config?", config); + base = replace_all_distinct(base, "?localport?", to_string(local_port)); + + return base; +} +*/ +void explodeVmess(std::string vmess, std::string custom_port, int local_port, nodeInfo &node) +{ + std::string version, ps, add, port, type, id, aid, net, path, host, tls; + Document jsondata; + std::vector vArray; + if(regMatch(vmess, "vmess://(.*?)\\?(.*)")) //kitsunebi style link + { + explodeKitsunebi(vmess, custom_port, local_port, node); + return; + } + else if(regMatch(vmess, "vmess1://(.*?)\\?(.*)")) // new kitsunebi style link + { + explodeKitsunebiNew(vmess, custom_port, local_port, node); + return; + } + vmess = urlsafe_base64_decode(regReplace(vmess, "(vmess|vmess1)://", "")); + if(regMatch(vmess, "(.*?) = (.*)")) + { + explodeQuan(vmess, custom_port, local_port, node); + return; + } + jsondata.Parse(vmess.data()); + + version = "1"; //link without version will treat as version 1 + GetMember(jsondata, "v", &version); //try to get version + + jsondata["ps"] >> ps; + jsondata["add"] >> add; + jsondata["type"] >> type; + jsondata["id"] >> id; + jsondata["aid"] >> aid; + jsondata["net"] >> net; + jsondata["tls"] >> tls; + if(custom_port != "") + port = custom_port; + else + jsondata["port"] >> port; + + jsondata["host"] >> host; + if(version == "1") + { + if(host != "") + { + vArray = split(host, ";"); + if(vArray.size() == 2) + { + host = vArray[0]; + path = vArray[1]; + } + } + } + else if(version == "2") + { + path = GetMember(jsondata, "path"); + } + + node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; + node.group = V2RAY_DEFAULT_GROUP; + node.remarks = ps; + node.server = add; + node.port = stoi(port); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, "auto", path, host, tls, local_port); +} + +void explodeVmessConf(std::string content, std::string custom_port, int local_port, bool libev, std::vector &nodes) +{ + nodeInfo node; + Document json; + std::string group, ps, add, port, type, id, aid, net, path, host, tls, cipher, subid; + int configType, index = nodes.size(); + std::map subdata; + std::map::iterator iter; + + json.Parse(content.data()); + if(json.HasMember("outbounds")) //single config + { + if(json["outbounds"].Size() > 0 && json["outbounds"][0].HasMember("settings") && json["outbounds"][0]["settings"].HasMember("vnext") && json["outbounds"][0]["settings"]["vnext"].Size() > 0) + { + add = GetMember(json["outbounds"][0]["settings"]["vnext"][0], "address"); + port = GetMember(json["outbounds"][0]["settings"]["vnext"][0], "port"); + json["routing"].RemoveAllMembers(); + json["routing"].AddMember("domainStrategy", "IPIfNonMatch", json.GetAllocator()); + rapidjson::Value& inbounds = json["inbounds"]; + rapidjson::Document newinbound(Type::kObjectType); + newinbound.AddMember("listen", "127.0.0.1", json.GetAllocator()); + newinbound.AddMember("port", local_port, json.GetAllocator()); + newinbound.AddMember("protocol", "socks", json.GetAllocator()); + inbounds.Clear(); + inbounds.PushBack(newinbound, json.GetAllocator()); + node.proxyStr = SerializeObject(json); + node.group = V2RAY_DEFAULT_GROUP; + node.remarks = add + ":" + port; + node.server = add; + node.port = stoi(port); + nodes.push_back(node); + } + return; + } + //read all subscribe remark as group name + for(unsigned int i = 0; i < json["subItem"].Size(); i++) + { + subdata.insert(std::pair(json["subItem"][i]["id"].GetString(), json["subItem"][i]["remarks"].GetString())); + } + + for(unsigned int i = 0; i < json["vmess"].Size(); i++) + { + if(json["vmess"][i]["address"].IsNull() || json["vmess"][i]["port"].IsNull() || json["vmess"][i]["id"].IsNull()) + { + continue; + } + //common info + json["vmess"][i]["remarks"] >> ps; + json["vmess"][i]["address"] >> add; + if(custom_port != "") + port = custom_port; + else + json["vmess"][i]["port"] >>port; + json["vmess"][i]["subid"] >> subid; + + if(subid != "") + { + iter = subdata.find(subid); + if(iter != subdata.end()) + { + group = iter->second; + } + } + if(ps == "") + { + ps = add + ":" + port; + } + + json["vmess"][i]["configType"] >> configType; + switch(configType) + { + case 1: //vmess config + json["vmess"][i]["headerType"] >> type; + json["vmess"][i]["id"] >> id; + json["vmess"][i]["alterId"] >> aid; + json["vmess"][i]["network"] >> net; + json["vmess"][i]["path"] >> path; + json["vmess"][i]["requestHost"] >> host; + json["vmess"][i]["streamSecurity"] >> tls; + 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); + break; + case 3: //ss config + json["vmess"][i]["id"] >> id; + json["vmess"][i]["security"] >> cipher; + group = SS_DEFAULT_GROUP; + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.proxyStr = ssConstruct(add, port, id, cipher, "", "", ps, local_port, true); + break; + case 4: //socks config + group = SOCKS_DEFAULT_GROUP; + node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; + node.proxyStr = "user=&pass="; + default: + continue; + } + + node.group = group; + node.remarks = ps; + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.id = index; + node.server = add; + node.port = stoi(port); + nodes.push_back(node); + } + return; +} + +void explodeSS(std::string ss, bool libev, std::string custom_port, int local_port, nodeInfo &node) +{ + std::string ps, password, method, server, port, plugins, plugin, pluginopts, addition, group = SS_DEFAULT_GROUP; + std::vector args, secret; + ss = replace_all_distinct(replace_all_distinct(ss.substr(5), "\r", ""), "/?", "?"); + if(strFind(ss, "#")) + { + ps = UrlDecode(ss.substr(ss.find("#") + 1)); + ss = ss.substr(0, ss.find("#")); + } + + if(strFind(ss, "?")) + { + addition = ss.substr(ss.find("?") + 1); + plugins = UrlDecode(getUrlArg(addition, "plugin")); + plugin = plugins.substr(0, plugins.find(";")); + pluginopts = plugins.substr(plugins.find(";") + 1); + if(getUrlArg(addition, "group") != "") + group = urlsafe_base64_decode(getUrlArg(addition, "group")); + ss = ss.substr(0, ss.find("?")); + } + if(strFind(ss, "@")) + { + ss = regReplace(ss, "(.*?)@(.*):(.*)", "$1,$2,$3"); + args = split(ss, ","); + secret = split(urlsafe_base64_decode(args[0]), ":"); + method = secret[0]; + password = secret[1]; + server = args[1]; + port = custom_port == "" ? args[2] : custom_port; + } + else + { + ss = regReplace(urlsafe_base64_decode(ss), "(.*?):(.*?)@(.*):(.*)", "$1,$2,$3,$4"); + args = split(ss, ","); + method = args[0]; + password = args[1]; + server = args[2]; + port = custom_port == "" ? args[3] : custom_port; + } + if(ps == "") + ps = server + ":" + port; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.group = group; + node.remarks = ps; + node.server = server; + node.port = stoi(port); + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, ps, local_port, libev); +} + +void explodeSSD(std::string link, bool libev, std::string custom_port, int local_port, std::vector &nodes) +{ + Document jsondata; + nodeInfo node; + unsigned int index = nodes.size(); + std::string group, port, method, password, server, remarks; + std::string plugin, pluginopts; + link = urlsafe_base64_decode(link.substr(6)); + jsondata.Parse(link.c_str()); + if(!jsondata.HasMember("servers")) + return; + for(unsigned int i = 0; i < jsondata["servers"].Size(); i++) + { + jsondata["airport"] >> group; + jsondata["servers"][i]["remarks"] >> remarks; + jsondata["port"] >> port; + jsondata["encryption"] >> method; + jsondata["password"] >> password; + jsondata["servers"][i]["server"] >> server; + GetMember(jsondata["servers"][i], "plugin", &plugin); + GetMember(jsondata["servers"][i], "plugin_options", &pluginopts); + GetMember(jsondata["servers"][i], "encryption", &method); + GetMember(jsondata["servers"][i], "port", &port); + GetMember(jsondata["servers"][i], "password", &password); + + if(custom_port != "") + port = custom_port; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.group = group; + node.remarks = remarks; + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.server = server; + node.port = stoi(port); + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev); + node.id = index; + nodes.push_back(node); + index++; + } + return; +} + +void explodeSSAndroid(std::string ss, bool libev, std::string custom_port, int local_port, std::vector &nodes) +{ + Document json; + nodeInfo node; + std::string ps, password, method, server, port, group = SS_DEFAULT_GROUP; + int index = nodes.size(); + //first add some extra data before parsing + ss = "{\"nodes\":" + ss + "}"; + json.Parse(ss.data()); + + for(unsigned int i = 0; i < json["nodes"].Size(); i++) + { + json["nodes"][i]["remarks"] >> ps; + json["nodes"][i]["server"] >> server; + if(custom_port != "") + port = custom_port; + else + json["nodes"][i]["server_port"] >> port; + if(ps == "") + ps = server + ":" + port; + json["nodes"][i]["password"] >> password; + json["nodes"][i]["method"] >> method; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.id = index; + node.group = group; + node.remarks = ps; + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.server = server; + node.port = stoi(port); + node.proxyStr = ssConstruct(server, port, password, method, "", "", ps, local_port, libev); + nodes.push_back(node); + index++; + } +} + +void explodeSSConf(std::string content, std::string custom_port, int local_port, bool libev, std::vector &nodes) +{ + nodeInfo node; + Document json; + std::string ps, password, method, server, port, plugin, pluginopts, group = SS_DEFAULT_GROUP; + int index = nodes.size(); + + json.Parse(content.data()); + if(json.HasMember("local_port") && json.HasMember("local_address")) //single libev config + { + server = GetMember(json, "server"); + port = GetMember(json, "server_port"); + json["local_port"].SetInt(local_port); + json["local_address"].SetString("127.0.0.1"); + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.group = SS_DEFAULT_GROUP; + node.remarks = server + ":" + port; + node.server = server; + node.port = stoi(port); + node.proxyStr = SerializeObject(json); + nodes.push_back(node); + return; + } + for(unsigned int i = 0; i < json["configs"].Size(); i++) + { + json["configs"][i]["remarks"] >> ps; + if(custom_port != "") + port = custom_port; + else + json["configs"][i]["server_port"] >> port; + if(ps == "") + { + ps = server + ":" + port; + } + + json["configs"][i]["password"] >> password; + json["configs"][i]["method"] >> method; + json["configs"][i]["server"] >> server; + json["configs"][i]["plugin"] >> plugin; + json["configs"][i]["plugin_opts"] >> pluginopts; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.group = group; + node.remarks = ps; + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.id = index; + node.server = server; + node.port = stoi(port); + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, ps, local_port, libev); + nodes.push_back(node); + index++; + } + return; +} + +void explodeSSR(std::string ssr, bool ss_libev, bool ssr_libev, std::string custom_port, int local_port, nodeInfo &node) +{ + std::string strobfs; + std::vector strcfg; + std::string remarks, group, server, port, method, password, protocol, protoparam, obfs, obfsparam, remarks_base64; + ssr = replace_all_distinct(ssr.substr(6), "\r", ""); + ssr = urlsafe_base64_decode(ssr); + if(strFind(ssr, "/?")) + { + strobfs = ssr.substr(ssr.find("/?") + 2); + ssr = ssr.substr(0, ssr.find("/?")); + group = urlsafe_base64_decode(getUrlArg(strobfs, "group")); + remarks = urlsafe_base64_decode(getUrlArg(strobfs, "remarks")); + remarks_base64 = urlsafe_base64_reverse(getUrlArg(strobfs, "remarks")); + obfsparam = urlsafe_base64_decode(getUrlArg(strobfs, "obfsparam")); + protoparam = urlsafe_base64_decode(getUrlArg(strobfs, "protoparam")); + } + + ssr = regReplace(ssr, "(.*):(.*?):(.*?):(.*?):(.*?):(.*)", "$1,$2,$3,$4,$5,$6"); + strcfg = split(ssr, ","); + + if(strcfg.size() != 6) + return; + + server = strcfg[0]; + port = custom_port == "" ? strcfg[1] : custom_port; + protocol = strcfg[2]; + method = strcfg[3]; + obfs = strcfg[4]; + password = urlsafe_base64_decode(strcfg[5]); + + if(group == "") + group = SSR_DEFAULT_GROUP; + if(remarks == "") + { + remarks = server + ":" + port; + remarks_base64 = base64_encode(remarks); + } + + node.group = group; + node.remarks = remarks; + node.server = server; + node.port = stoi(port); + if(find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() && (obfs == "" || obfs == "plain") && (protocol == "" || protocol == "origin")) + { + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.proxyStr = ssConstruct(server, port, password, method, "", "", remarks, local_port, ss_libev); + } + else + { + node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; + node.proxyStr = ssrConstruct(group, remarks, remarks_base64, server, port, protocol, method, obfs, password, obfsparam, protoparam, local_port, ssr_libev); + } +} + +void explodeSSRConf(std::string content, std::string custom_port, int local_port, bool ss_libev, bool ssr_libev, std::vector &nodes) +{ + nodeInfo node; + Document json; + std::string remarks, remarks_base64, group, server, port, method, password, protocol, protoparam, obfs, obfsparam; + int index = nodes.size(); + + json.Parse(content.data()); + if(json.HasMember("local_port") && json.HasMember("local_address")) //single libev config + { + method = GetMember(json, "method"); + obfs = GetMember(json, "obfs"); + protocol = GetMember(json, "protocol"); + if(find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() && (obfs == "" || obfs == "plain") && (protocol == "" || protocol == "origin")) + { + explodeSSConf(content, custom_port, local_port, ss_libev, nodes); + return; + } + server = GetMember(json, "server"); + port = GetMember(json, "server_port"); + json["local_port"].SetInt(local_port); + json["local_address"].SetString("127.0.0.1"); + node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; + node.group = SSR_DEFAULT_GROUP; + node.remarks = server + ":" + port; + node.server = server; + node.port = stoi(port); + node.proxyStr = SerializeObject(json); + nodes.push_back(node); + return; + } + for(unsigned int i = 0; i < json["configs"].Size(); i++) + { + json["configs"][i]["group"] >> group; + if(group == "") + group = SSR_DEFAULT_GROUP; + json["configs"][i]["remarks"] >> remarks; + json["configs"][i]["server"] >> server; + if(custom_port != "") + port = custom_port; + else + json["configs"][i]["server_port"] >> port; + if(remarks == "") + remarks = server + ":" + port; + + json["configs"][i]["remarks_base64"] >> remarks_base64; + json["configs"][i]["password"] >> password; + json["configs"][i]["method"] >> method; + + json["configs"][i]["protocol"] >> protocol; + json["configs"][i]["protocolparam"] >> protoparam; + json["configs"][i]["obfs"] >> obfs; + json["configs"][i]["obfsparam"] >> obfsparam; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; + node.group = group; + node.remarks = remarks; + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.id = index; + node.server = server; + node.port = stoi(port); + node.proxyStr = ssrConstruct(group, remarks, remarks_base64, server, port, protocol, method, obfs, password, obfsparam, protoparam, local_port, ssr_libev); + nodes.push_back(node); + index++; + } + return; +} + +void explodeSocks(std::string link, std::string custom_port, nodeInfo &node) +{ + std::string remarks, server, port, username, password; + if(strFind(link, "socks://")) //v2rayn socks link + { + std::vector arguments; + if(strFind(link, "#")) + { + remarks = UrlDecode(link.substr(link.find("#") + 1)); + link = link.substr(0, link.find("#")); + } + link = urlsafe_base64_decode(link.substr(8)); + arguments = split(link, ":"); + server = arguments[0]; + port = arguments[1]; + } + else if(strFind(link, "https://t.me/socks") || strFind(link, "tg://socks")) //telegram style socks link + { + server = getUrlArg(link, "server"); + port = getUrlArg(link, "port"); + username = getUrlArg(link, "user"); + password = getUrlArg(link, "pass"); + } + if(remarks == "") + { + remarks = server + ":" + port; + } + if(custom_port != "") + { + port = custom_port; + } + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; + node.group = SOCKS_DEFAULT_GROUP; + node.remarks = remarks; + node.server = server; + node.port = stoi(port); + node.proxyStr = "user=" + username + "&pass=" + password; +} + +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::vector configs, vArray; + strTemp = regReplace(quan, "(.*?) = (.*)", "$1,$2"); + configs = split(strTemp, ","); + if(configs[1] == "vmess") + { + ps = trim(configs[0]); + add = trim(configs[2]); + port = trim(configs[3]); + cipher = trim(configs[4]); + id = trim(replace_all_distinct(configs[5], "\"", "")); + + //read link + for(unsigned int i = 6; i < configs.size(); i++) + { + vArray = split(configs[i], "="); + if(vArray.size() < 2) + 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") + { + std::vector 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(itemName == "obfs" && itemVal == "ws") + net = "ws"; + } + if(path == "") + path = "/"; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; + node.group = group; + node.remarks = ps; + node.server = add; + node.port = stoi(port); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, 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; + netch = urlsafe_base64_decode(netch.substr(8)); + + json.Parse(netch.data()); + json["Type"] >> type; + json["Remark"] >> remark; + json["Hostname"] >> address; + json["Port"] >> port; + method = GetMember(json, "EncryptMethod"); + password = GetMember(json, "Password"); + if(remark == "") + remark = address + ":" + port; + if(type == "SS") + { + plugin = GetMember(json, "Plugin"); + pluginopts = GetMember(json, "PluginOption"); + node.group = SS_DEFAULT_GROUP; + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, local_port, ss_libev); + } + else if(type == "SSR") + { + protocol = GetMember(json, "Protocol"); + obfs = GetMember(json, "OBFS"); + if(find(ss_ciphers.begin(), ss_ciphers.end(), method) != ss_ciphers.end() && (obfs == "" || obfs == "plain") && (protocol == "" || protocol == "origin")) + { + plugin = GetMember(json, "Plugin"); + pluginopts = GetMember(json, "PluginOption"); + node.group = SS_DEFAULT_GROUP; + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, local_port, ss_libev); + } + else + { + protoparam = GetMember(json, "ProtocolParam"); + obfsparam = GetMember(json, "OBFSParam"); + node.group = SSR_DEFAULT_GROUP; + node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; + node.proxyStr = ssrConstruct(SSR_DEFAULT_GROUP, remark, base64_encode(remark), address, port, protocol, method, obfs, password, obfsparam, protoparam, local_port, ssr_libev); + } + } + else if(type == "VMess") + { + id = GetMember(json, "UserID"); + aid = GetMember(json, "AlterID"); + transprot = GetMember(json, "TransferProtocol"); + faketype = GetMember(json, "FakeType"); + host = GetMember(json, "Host"); + path = GetMember(json, "Path"); + 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); + } + else if(type == "Socks5") + { + username = GetMember(json, "Username"); + node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; + node.group = SOCKS_DEFAULT_GROUP; + node.proxyStr = "user=" + username + "&pass=" + password; + } + else + return; + + node.remarks = remark; + node.server = address; + node.port = (unsigned short)stoi(port); +} + +void explodeClash(Node yamlnode, std::string custom_port, int local_port, std::vector &nodes, bool ss_libev, bool ssr_libev) +{ + nodeInfo node; + unsigned int index = nodes.size(); + std::string proxytype, strTemp, 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 + std::string user; //socks + for(unsigned int i = 0; i < yamlnode["Proxy"].size(); i++) + { + yamlnode["Proxy"][i]["type"] >> proxytype; + yamlnode["Proxy"][i]["name"] >> ps; + yamlnode["Proxy"][i]["server"] >> server; + port = custom_port == "" ? yamlnode["Proxy"][i]["port"].as() : custom_port; + if(proxytype == "vmess") + { + group = V2RAY_DEFAULT_GROUP; + + yamlnode["Proxy"][i]["uuid"] >> id; + yamlnode["Proxy"][i]["alterId"] >> aid; + yamlnode["Proxy"][i]["cipher"] >> cipher; + net = yamlnode["Proxy"][i]["network"].IsDefined() ? yamlnode["Proxy"][i]["network"].as() : "tcp"; + path = yamlnode["Proxy"][i]["ws-path"].IsDefined() ? yamlnode["Proxy"][i]["ws-path"].as() : "/"; + if(yamlnode["Proxy"][i]["tls"].IsDefined()) + tls = yamlnode["Proxy"][i]["tls"].as() == "true" ? "tls" : ""; + else + tls = ""; + if(yamlnode["Proxy"][i]["ws-headers"].IsDefined()) + yamlnode["Proxy"][i]["ws-headers"]["Host"] >> host; + else + host = ""; + + + node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; + node.proxyStr = vmessConstruct(server, port, type, id, aid, net, cipher, path, host, tls, local_port); + } + else if(proxytype == "ss") + { + group = SS_DEFAULT_GROUP; + + yamlnode["Proxy"][i]["cipher"] >> cipher; + yamlnode["Proxy"][i]["password"] >> password; + if(yamlnode["Proxy"][i]["plugin"].IsDefined()) + { + if(yamlnode["Proxy"][i]["plugin"].as() == "obfs") + { + plugin = "simple-obfs"; + if(yamlnode["Proxy"][i]["plugin-opts"].IsDefined()) + { + yamlnode["Proxy"][i]["plugin-opts"]["mode"] >> pluginopts_mode; + if(yamlnode["Proxy"][i]["plugin-opts"]["host"].IsDefined()) + yamlnode["Proxy"][i]["plugin-opts"]["host"] >> pluginopts_host; + } + } + } + else if(yamlnode["Proxy"][i]["obfs"].IsDefined()) + { + plugin = "simple-obfs"; + yamlnode["Proxy"][i]["obfs"] >> pluginopts_mode; + if(yamlnode["Proxy"][i]["obfs-host"].IsDefined()) + { + yamlnode["Proxy"][i]["obfs-host"] >> pluginopts_host; + } + } + else + plugin = ""; + + if(plugin != "") + { + pluginopts = "obfs=" + pluginopts_mode; + pluginopts += pluginopts_host == "" ? "" : ";obfs-host=" + pluginopts_host; + } + + //support for go-shadowsocks2 + if(cipher == "AEAD_CHACHA20_POLY1305") + cipher = "chacha20-ietf-poly1305"; + else if(strFind(cipher, "AEAD")) + { + cipher = replace_all_distinct(replace_all_distinct(cipher, "AEAD_", ""), "_", "-"); + std::transform(cipher.begin(), cipher.end(), cipher.begin(), ::tolower); + } + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.proxyStr = ssConstruct(server, port, password, cipher, plugin, pluginopts, ps, local_port, ss_libev); + } + else if(proxytype == "socks") + { + group = SOCKS_DEFAULT_GROUP; + + if(yamlnode["Proxy"][i]["username"].IsDefined() && yamlnode["Proxy"][i]["password"].IsDefined()) + { + yamlnode["Proxy"][i]["username"] >> user; + yamlnode["Proxy"][i]["password"] >> password; + } + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; + node.proxyStr = "user=" + user + "&pass=" + password; + } + else if(proxytype == "ssr") + { + group = SSR_DEFAULT_GROUP; + + yamlnode["Proxy"][i]["cipher"] >> cipher; + yamlnode["Proxy"][i]["password"] >> password; + yamlnode["Proxy"][i]["protocol"] >> protocol; + yamlnode["Proxy"][i]["protocolparam"] >> protoparam; + yamlnode["Proxy"][i]["obfs"] >> obfs; + yamlnode["Proxy"][i]["obfsparam"] >> obfsparam; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; + node.proxyStr = ssrConstruct(group, ps, base64_encode(ps), server, port, protocol, cipher, obfs, password, obfsparam, protoparam, local_port, ssr_libev); + } + else + continue; + + node.group = group; + node.remarks = ps; + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.server = server; + node.port = stoi(port); + node.id = index; + nodes.push_back(node); + index++; + } + return; +} + +void explodeKitsunebi(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 addition; + string_array userinfo; + kit = replace_all_distinct(kit, "vmess://", ""); + + addition = kit.substr(kit.find("?") + 1); + kit = kit.substr(0, kit.find("?")); + + userinfo = split(regReplace(urlsafe_base64_decode(kit), "(.*?):(.*?)@(.*):(.*)", "$1,$2,$3,$4"), ","); + cipher = userinfo[0]; + id = userinfo[1]; + add = userinfo[2]; + port = userinfo[3]; + remarks = UrlDecode(getUrlArg(addition, "remark")); + net = getUrlArg(addition, "network"); + aid = getUrlArg(addition, "aid"); + tls = getUrlArg(addition, "tls") == "1" ? "tls" : ""; + host = getUrlArg(addition, "wsHost"); + path = getUrlArg(addition, "wspath"); + + if(remarks == "") + remarks = add + ":" + port; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; + node.group = V2RAY_DEFAULT_GROUP; + node.remarks = remarks; + node.server = add; + node.port = stoi(port); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, tls, local_port); +} + +void explodeKitsunebiNew(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 addition; + string_array userinfo; + kit = replace_all_distinct(kit, "vmess1://", ""); + + if(strFind(kit, "#")) + { + remarks = kit.substr(kit.find("#") + 1); + kit = kit.substr(0, kit.find("#")); + } + + addition = kit.substr(kit.find("?") + 1); + kit = kit.substr(0, kit.find("?")); + + userinfo = split(regReplace(kit, "(.*?)@(.*):(.*)", "$1,$2,$3"), ","); + id = userinfo[0]; + add = userinfo[1]; + if(strFind(userinfo[2], "/")) + { + port = userinfo[2].substr(0, userinfo[2].find("/")); + path = userinfo[2].substr(userinfo[2].find("/")); + } + else + { + port = userinfo[2]; + } + net = getUrlArg(addition, "network"); + tls = getUrlArg(addition, "tls") == "true" ? "tls" : ""; + host = getUrlArg(addition, "ws.host"); + + if(remarks == "") + remarks = add + ":" + port; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; + node.group = V2RAY_DEFAULT_GROUP; + node.remarks = remarks; + node.server = add; + node.port = stoi(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 line, remarks, server, port, method, username, password, plugin, pluginopts, pluginopts_mode, pluginopts_host = "cloudfront.net", mod_url, mod_md5; + std::string id, net, tls, host, path; + std::string itemName, itemVal; + std::stringstream data; + std::vector configs, vArray, headers, header; + std::multimap proxies; + nodeInfo node; + unsigned int i, index = nodes.size(); + INIReader ini; + + /* + if(!strFind(surge, "[Proxy]")) + return false; + */ + + ini.store_isolated_line = true; + ini.SetIsolatedItemsSection("Proxy"); + ini.IncludeSection("Proxy"); + ini.Parse(surge); + + if(!ini.SectionExist("Proxy")) + return false; + ini.EnterSection("Proxy"); + ini.GetItems(proxies); + + for(auto &x : proxies) + { + remarks = x.first; + configs = split(x.second, ","); + if(configs.size() < 2 || configs[0] == "direct") + continue; + else if(configs[0] == "custom") //surge 2 style custom proxy + { + mod_url = trim(configs[5]); + if(parsedMD5.count(mod_url) > 0) + { + mod_md5 = parsedMD5[mod_url]; //read calculated MD5 from map + } + else + { + mod_md5 = getMD5(webGet(mod_url)); //retrieve module and calculate MD5 + parsedMD5.insert(std::pair(mod_url, mod_md5)); //save unrecognized module MD5 to map + } + + if(mod_md5 == modSSMD5) //is SSEncrypt module + { + server = trim(configs[1]); + port = custom_port == "" ? trim(configs[2]) : custom_port; + method = trim(configs[3]); + password = trim(configs[4]); + plugin = ""; + + for(i = 6; i < configs.size(); i++) + { + vArray = split(trim(configs[i]), "="); + if(vArray.size() < 2) + continue; + itemName = trim(vArray[0]); + itemVal = trim(vArray[1]); + if(itemName == "obfs") + { + plugin = "simple-obfs"; + pluginopts_mode = itemVal; + } + else if(itemVal == "obfs-host") + pluginopts_host = itemVal; + } + if(plugin != "") + { + pluginopts = "obfs=" + pluginopts_mode; + pluginopts += pluginopts_host == "" ? "" : ";obfs-host=" + pluginopts_host; + } + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.group = SS_DEFAULT_GROUP; + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev); + } + else + continue; + } + else if(configs[0] == "ss") //surge 3 style ss proxy + { + server = trim(configs[1]); + port = custom_port == "" ? trim(configs[2]) : custom_port; + plugin = ""; + + for(i = 3; i < configs.size(); i++) + { + vArray = split(trim(configs[i]), "="); + if(vArray.size() < 2) + continue; + itemName = trim(vArray[0]); + itemVal = trim(vArray[1]); + if(itemName == "encrypt-method") + method = itemVal; + else if(itemName == "password") + password = itemVal; + else if(itemName == "obfs") + { + plugin = "simple-obfs"; + pluginopts_mode = itemVal; + } + else if(itemName == "obfs-host") + pluginopts_host = itemVal; + } + if(plugin != "") + { + pluginopts = "obfs=" + pluginopts_mode; + pluginopts += pluginopts_host == "" ? "" : ";obfs-host=" + pluginopts_host; + } + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.group = SS_DEFAULT_GROUP; + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev); + } + else if(configs[0] == "socks5") //surge 3 style socks5 proxy + { + node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; + node.group = SOCKS_DEFAULT_GROUP; + if(configs.size() >= 5) + { + username = trim(configs[2]); + password = trim(configs[3]); + } + node.proxyStr = "user=" + username + "&pass=" + password; + } + else if(configs[0] == "vmess") //surge 4 style vmess proxy + { + server = trim(configs[1]); + port = custom_port == "" ? trim(configs[2]) : custom_port; + net = "tcp"; + method = "auto"; + + for(i = 3; i < configs.size(); i++) + { + vArray = split(trim(configs[i]), "="); + if(vArray.size() != 2) + continue; + else if(vArray[0] == "username") + id = vArray[1]; + else if(vArray[0] == "ws") + { + if(vArray[1] == "true") + net = "ws"; + } + else if(vArray[0] == "tls") + { + if(vArray[1] == "true") + tls = "tls"; + } + else if(vArray[0] == "ws-path") + path = vArray[1]; + else if(vArray[0] == "ws-headers") + { + headers = split(trim(vArray[1]), "|"); + for(auto &y : headers) + { + header = split(trim(y), ":"); + if(header[0] == "Host") + host = header[1]; + } + + } + } + if(host == "" && !isIPv4(server) && !isIPv6(server)) + host = server; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; + node.group = V2RAY_DEFAULT_GROUP; + node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, tls, local_port); + } + else if(remarks == "shadowsocks") //quantumult style ss link + { + server = trim(configs[0].substr(0, configs[0].rfind(":"))); + port = custom_port == "" ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port; + plugin = remarks = ""; + + for(i = 1; i < configs.size(); i++) + { + vArray = split(trim(configs[i]), "="); + if(vArray.size() != 2) + continue; + else if(vArray[0] == "method") + method = vArray[1]; + else if(vArray[0] == "password") + password = vArray[1]; + else if(vArray[0] == "tag") + remarks = vArray[1]; + } + if(remarks == "") + remarks = server + ":" + port; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.group = SS_DEFAULT_GROUP; + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, local_port, libev); + } + else + continue; + + node.remarks = remarks; + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.server = server; + node.port = stoi(port); + node.id = index; + nodes.push_back(node); + index++; + } + return true; +} + +void explodeSSTap(std::string sstap, std::string custom_port, int local_port, std::vector &nodes, bool ss_libev, bool ssr_libev) +{ + Document json; + nodeInfo node; + std::string configType, group, remarks, server, port; + std::string cipher; + std::string user, pass; + std::string protocol, protoparam, obfs, obfsparam; + unsigned int index = nodes.size(); + json.Parse(sstap.data()); + + for(unsigned int i = 0; i < json["configs"].Size(); i++) + { + json["configs"][i]["group"] >> group; + json["configs"][i]["remarks"] >> remarks; + json["configs"][i]["server"] >> server; + json["configs"][i]["server_port"] >> port; + + if(remarks == "") + remarks = server + ":" + port; + + json["configs"][i]["password"] >> pass; + json["configs"][i]["type"] >> configType; + if(configType == "5") //socks 5 + { + json["configs"][i]["username"] >> user; + node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; + node.proxyStr = "user=" + user + "&pass=" + pass; + } + else if(configType == "6") //ss/ssr + { + json["configs"][i]["protocol"] >> protocol; + json["configs"][i]["obfs"] >> obfs; + json["configs"][i]["method"] >> cipher; + if(find(ss_ciphers.begin(), ss_ciphers.end(), cipher) != ss_ciphers.end() && protocol == "origin" && obfs == "plain") //is ss + { + node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; + node.proxyStr = ssConstruct(server, port, pass, cipher, "", "", remarks, local_port, ss_libev); + } + else //is ssr cipher + { + json["configs"][i]["obfsparam"] >> obfsparam; + json["configs"][i]["protocolparam"] >> protoparam; + node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; + node.proxyStr = ssrConstruct(group, remarks, base64_encode(remarks), server, port, protocol, cipher, obfs, pass, obfsparam, protoparam, local_port, ssr_libev); + } + } + else + continue; + + node.group = group; + node.remarks = remarks; + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.id = index; + node.server = server; + node.port = stoi(port); + nodes.push_back(node); + } +} + +void explodeNetchConf(std::string netch, bool ss_libev, bool ssr_libev, std::string custom_port, int local_port, std::vector &nodes) +{ + Document json; + nodeInfo node; + unsigned int index = nodes.size(); + + json.Parse(netch.data()); + + if(!json.HasMember("Server")) + return; + + for(unsigned int i = 0; i < json["Server"].Size(); i++) + { + explodeNetch("Netch://" + base64_encode(SerializeObject(json["Server"][i])), ss_libev, ssr_libev, custom_port, local_port, node); + + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + + node.id = index; + nodes.push_back(node); + index++; + } +} + +bool chkIgnore(nodeInfo &node) +{ + 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; + } + if(include_remarks.size() != 0) + { + writeLog(LOG_TYPE_INFO, "Comparing include remarks..."); + for(auto &x : include_remarks) + { + if(regFind(remarks, x)) + included = true; + } + } + else + { + included = true; + } + + return excluded || !included; +} + +int explodeConf(std::string filepath, std::string custom_port, int local_port, bool sslibev, bool ssrlibev, std::vector &nodes) +{ + std::ifstream infile; + std::stringstream contentstrm; + infile.open(filepath); + + contentstrm << infile.rdbuf(); + infile.close(); + + return explodeConfContent(contentstrm.str(), custom_port, local_port, sslibev, ssrlibev, nodes); +} + +int explodeConfContent(std::string content, std::string custom_port, int local_port, bool sslibev, bool ssrlibev, std::vector &nodes) +{ + unsigned int index = 0; + int filetype = -1; + std::vector::iterator iter; + + if(strFind(content, "\"version\"")) + filetype = SPEEDTEST_MESSAGE_FOUNDSS; + else if(strFind(content, "\"serverSubscribes\"")) + filetype = SPEEDTEST_MESSAGE_FOUNDSSR; + else if(strFind(content, "\"uiItem\"") || strFind(content, "vnext")) + filetype = SPEEDTEST_MESSAGE_FOUNDVMESS; + else if(strFind(content, "\"proxy_apps\"")) + filetype = SPEEDTEST_MESSAGE_FOUNDSSCONF; + else if(strFind(content, "\"idInUse\"")) + filetype = SPEEDTEST_MESSAGE_FOUNDSSTAP; + else if(strFind(content, "\"local_address\"") && strFind(content, "\"local_port\"")) + filetype = SPEEDTEST_MESSAGE_FOUNDSSR; //use ssr config parser + else if(strFind(content, "\"ModeFileNameType\"")) + filetype = SPEEDTEST_MESSAGE_FOUNDNETCH; + + switch(filetype) + { + case SPEEDTEST_MESSAGE_FOUNDSS: + explodeSSConf(content, custom_port, local_port, sslibev, nodes); + break; + case SPEEDTEST_MESSAGE_FOUNDSSR: + explodeSSRConf(content, custom_port, local_port, sslibev, ssrlibev, nodes); + break; + case SPEEDTEST_MESSAGE_FOUNDVMESS: + explodeVmessConf(content, custom_port, local_port, sslibev, nodes); + break; + case SPEEDTEST_MESSAGE_FOUNDSSCONF: + explodeSSAndroid(content, sslibev, custom_port, local_port, nodes); + break; + case SPEEDTEST_MESSAGE_FOUNDSSTAP: + explodeSSTap(content, custom_port, local_port, nodes, sslibev, ssrlibev); + break; + case SPEEDTEST_MESSAGE_FOUNDNETCH: + explodeNetchConf(content, sslibev, ssrlibev, custom_port, local_port, nodes); + break; + default: + //try to parse as a local subscription + explodeSub(content, sslibev, ssrlibev, custom_port, local_port, nodes); + if(nodes.size() == 0) + return SPEEDTEST_ERROR_UNRECOGFILE; + else + return SPEEDTEST_ERROR_NONE; + } + + iter = nodes.begin(); + while(iter != nodes.end()) + { + if(chkIgnore(*iter)) + { + writeLog(LOG_TYPE_INFO, "Node " + iter->group + " - " + iter->remarks + " has been ignored and will not be tested."); + nodes.erase(iter); + } + else + { + writeLog(LOG_TYPE_INFO, "Node " + iter->group + " - " + iter->remarks + " has been added."); + iter->id = index; + index++; + iter++; + } + } + + return SPEEDTEST_ERROR_NONE; +} + +void explode(std::string link, bool sslibev, bool ssrlibev, std::string custom_port, int local_port, nodeInfo &node) +{ + if(strFind(link, "ssr://")) + explodeSSR(link, sslibev, ssrlibev, custom_port, local_port, node); + else if(strFind(link, "vmess://") || strFind(link, "vmess1://")) + explodeVmess(link, custom_port, local_port, node); + else if(strFind(link, "ss://")) + explodeSS(link, sslibev, custom_port, local_port, node); + else if(strFind(link, "socks://") || strFind(link, "https://t.me/socks") || strFind(link, "tg://socks")) + explodeSocks(link, custom_port, node); + else if(strFind(link, "Netch://")) + explodeNetch(link, sslibev, ssrlibev, custom_port, local_port, node); +} + +void explodeSub(std::string sub, bool sslibev, bool ssrlibev, std::string custom_port, int local_port, std::vector &nodes) +{ + std::stringstream strstream; + std::string strLink; + nodeInfo node; + + //try to parse as surge configuration + if(explodeSurge(sub, custom_port, local_port, nodes, sslibev)) + { + return; + } + + //try to parse as clash configuration + try + { + if(strFind(sub, "Proxy")) + { + Node yamlnode = Load(sub); + if(yamlnode.size() && yamlnode["Proxy"]) + { + explodeClash(yamlnode, custom_port, local_port, nodes, sslibev, ssrlibev); + return; + } + } + } + catch (std::exception &e) + { + //ignore + } + + //try to parse as SSD configuration + if(strFind(sub, "ssd://")) + { + explodeSSD(sub, sslibev, custom_port, local_port, nodes); + return; + } + + //try to parse as normal subscription + sub = urlsafe_base64_decode(sub); + strstream << sub; + unsigned int index = nodes.size(); + char delimiter = split(sub, "\n").size() <= 1 ? split(sub, "\r").size() <= 1 ? ' ' : '\r' : '\n'; + while(getline(strstream, strLink, delimiter)) + { + explode(strLink, sslibev, ssrlibev, custom_port, local_port, node); + if(strLink.size() == 0 || node.linkType == -1) + { + continue; + } + if(chkIgnore(node)) + { + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been ignored and will not be tested."); + continue; + } + else + writeLog(LOG_TYPE_INFO, "Node " + node.group + " - " + node.remarks + " has been added."); + node.id = index; + nodes.push_back(node); + index++; + } +} + +void remarksInit(string_array &exclude, string_array &include) +{ + exclude_remarks = exclude; + include_remarks = include; +} + +int appendClashRules(YAML::Node &base, YAML::Node &rules) +{ + if(rules["Proxy Group"].IsDefined()) + base["Proxy Group"].reset(rules["Proxy Group"]); + if(rules["Rule"].IsDefined()) + base["Rule"].reset(rules["Rule"]); + return 0; +} diff --git a/speedtestutil.h b/speedtestutil.h new file mode 100644 index 0000000..b32be41 --- /dev/null +++ b/speedtestutil.h @@ -0,0 +1,27 @@ +#ifndef SPEEDTESTUTIL_H_INCLUDED +#define SPEEDTESTUTIL_H_INCLUDED + +#include +#include + +#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 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); +void explodeVmess(std::string vmess, std::string custom_port, int local_port, nodeInfo &node); +void explodeSSR(std::string ssr, bool ss_libev, bool libev, std::string custom_port, int local_port, nodeInfo &node); +void explodeSS(std::string ss, bool libev, std::string custom_port, int local_port, nodeInfo &node); +void explodeQuan(std::string quan, std::string custom_port, int local_port, nodeInfo &node); +void explodeKitsunebi(std::string kit, std::string custom_port, int local_port, nodeInfo &node); +void explodeKitsunebiNew(std::string kit, std::string custom_port, int local_port, nodeInfo &node); +void explode(std::string link, bool sslibev, bool ssrlibev, std::string custom_port, int local_port, nodeInfo &node); +void explodeSSD(std::string link, bool libev, std::string custom_port, int local_port, std::vector &nodes); +void explodeSub(std::string sub, bool sslibev, bool ssrlibev, std::string custom_port, int local_port, std::vector &nodes); +int explodeConf(std::string filepath, std::string custom_port, int local_port, bool sslibev, bool ssrlibev, std::vector &nodes); +int explodeConfContent(std::string content, std::string custom_port, int local_port, bool sslibev, bool ssrlibev, std::vector &nodes); +void remarksInit(string_array &exclude, string_array &include); +bool chkIgnore(nodeInfo &node); + +#endif // SPEEDTESTUTIL_H_INCLUDED diff --git a/subexport.cpp b/subexport.cpp new file mode 100644 index 0000000..9f82999 --- /dev/null +++ b/subexport.cpp @@ -0,0 +1,415 @@ +#include "misc.h" +#include "speedtestutil.h" +#include "ini_reader.h" +#include "rapidjson_extra.h" +#include "yamlcpp_extra.h" +#include "webget.h" +#include "subexport.h" + +#include +#include +#include +#include + +extern bool overwrite_original_rules; +extern string_array renames, emojis; +extern bool add_emoji, remove_old_emoji; + +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) +{ + rapidjson::StringBuffer sb; + rapidjson::Writer writer(sb); + writer.StartObject(); + writer.Key("Type"); + writer.String("VMess"); + writer.Key("Remark"); + writer.String(std::string(add + ":" + port).data()); + writer.Key("Hostname"); + writer.String(add.data()); + writer.Key("Port"); + writer.Int(shortAssemble((unsigned short)stoi(port), (unsigned short)local_port)); + writer.Key("UserID"); + writer.String(id.data()); + writer.Key("AlterID"); + writer.Int(stoi(aid)); + writer.Key("EncryptMethod"); + writer.String(cipher.data()); + writer.Key("TransferProtocol"); + writer.String(net.data()); + if(net == "ws") + { + writer.Key("Host"); + writer.String(host.data()); + writer.Key("Path"); + writer.String(path.data()); + } + else + { + if(net == "quic") + { + writer.Key("QUICSecure"); + writer.String(host.data()); + writer.Key("QUICSecret"); + writer.String(path.data()); + } + writer.Key("FakeType"); + writer.String(type.data()); + } + writer.Key("TLSSecure"); + writer.Bool(tls == "tls"); + writer.EndObject(); + return sb.GetString(); +} + +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) +{ + rapidjson::StringBuffer sb; + rapidjson::Writer writer(sb); + writer.StartObject(); + writer.Key("Type"); + writer.String("SSR"); + writer.Key("Remark"); + writer.String(remarks.data()); + writer.Key("Hostname"); + writer.String(server.data()); + writer.Key("Port"); + writer.Int(shortAssemble((unsigned short)stoi(port), (unsigned short)local_port)); + writer.Key("Password"); + writer.String(password.data()); + writer.Key("EncryptMethod"); + writer.String(method.data()); + writer.Key("Protocol"); + writer.String(protocol.data()); + writer.Key("ProtocolParam"); + writer.String(protoparam.data()); + writer.Key("OBFS"); + writer.String(obfs.data()); + writer.Key("OBFSParam"); + writer.String(obfsparam.data()); + writer.EndObject(); + return sb.GetString(); +} + +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) +{ + rapidjson::StringBuffer sb; + rapidjson::Writer writer(sb); + writer.StartObject(); + writer.Key("Type"); + writer.String("SS"); + writer.Key("Remark"); + writer.String(remarks.data()); + writer.Key("Hostname"); + writer.String(server.data()); + writer.Key("Port"); + writer.Int(shortAssemble((unsigned short)stoi(port), (unsigned short)local_port)); + writer.Key("Password"); + writer.String(password.data()); + writer.Key("EncryptMethod"); + writer.String(method.data()); + writer.Key("Plugin"); + writer.String(plugin.data()); + writer.Key("PluginOption"); + writer.String(pluginopts.data()); + writer.EndObject(); + return sb.GetString(); +} + +std::string nodeRename(std::string remark) +{ + string_array vArray; + + for(std::string &x : renames) + { + vArray = split(x, "@"); + if(vArray.size() == 1) + { + remark = regReplace(remark, vArray[0], ""); + } + else if(vArray.size() == 2) + { + remark = regReplace(remark, vArray[0], vArray[1]); + } + else + continue; + } + return remark; +} + +std::string removeEmoji(std::string remark) +{ + if(!remove_old_emoji) + return remark; + char emoji_id[2] = {(char)-16, (char)-97}; + while(true) + { + if(remark[0] == emoji_id[0] && remark[1] == emoji_id[1]) + remark = remark.substr(4); + else + break; + } + return remark; +} + +std::string addEmoji(std::string remark) +{ + if(!add_emoji) + return remark; + string_array vArray; + for(std::string &x : emojis) + { + vArray = split(x, ","); + if(vArray.size() != 2) + continue; + if(regFind(remark, vArray[0])) + { + remark = vArray[1] + " " + remark; + break; + } + } + return remark; +} + +void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset_content_array) +{ + string_array allRules, vArray; + std::string rule_group, rule_path, retrived_rules, strLine; + std::stringstream strStrm; + YAML::Node Rules; + + if(!overwrite_original_rules) + Rules = base_rule["Rule"]; + + for(ruleset_content &x : ruleset_content_array) + { + rule_group = x.rule_group; + retrived_rules = x.rule_content; + if(retrived_rules.find("[]") == 0) + { + allRules.emplace_back(retrived_rules.substr(2) + "," + rule_group); + continue; + } + char delimiter = count(retrived_rules.begin(), retrived_rules.end(), '\n') <= 1 ? '\r' : '\n'; + + strStrm.clear(); + strStrm< &nodes, std::string &baseConf, std::vector &ruleset_content_array, string_array &extra_proxy_group, bool clashR) +{ + YAML::Node yamlnode, proxies, singleproxy, singlegroup, original_groups; + rapidjson::Document json; + 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::vector nodelist; + bool tlssecure, replace_flag; + string_array vArray, filtered_nodelist; + + try + { + yamlnode = YAML::Load(baseConf); + } + catch (std::exception &e) + { + return std::string(); + } + + + for(nodeInfo &x : nodes) + { + singleproxy.reset(); + json.Parse(x.proxyStr.data()); + type = GetMember(json, "Type"); + remark = addEmoji(trim(removeEmoji(nodeRename(x.remarks)))); + hostname = GetMember(json, "Hostname"); + port = GetMember(json, "Port"); + username = GetMember(json, "Username"); + password = GetMember(json, "Password"); + method = GetMember(json, "EncryptMethod"); + + if(type == "SS") + { + plugin = GetMember(json, "Plugin"); + pluginopts = replace_all_distinct(GetMember(json, "PluginOption"), ";", "&"); + singleproxy["type"] = "ss"; + singleproxy["cipher"] = method; + if(plugin == "simple-obfs" || plugin == "obfs-local") + { + singleproxy["plugin"] = "obfs"; + singleproxy["plugin-opts"]["mode"] = UrlDecode(getUrlArg(pluginopts, "obfs")); + singleproxy["plugin-opts"]["host"] = UrlDecode(getUrlArg(pluginopts, "obfs-host")); + } + } + else if(type == "VMess") + { + id = GetMember(json, "UserID"); + aid = GetMember(json, "AlterID"); + transproto = GetMember(json, "TransferProtocol"); + host = GetMember(json, "Host"); + path = GetMember(json, "Path"); + tlssecure = GetMember(json, "TLSSecure") == "true"; + singleproxy["type"] = "vmess"; + singleproxy["uuid"] = id; + singleproxy["alterId"] = stoi(aid); + singleproxy["cipher"] = method; + singleproxy["tls"] = tlssecure; + if(transproto == "ws") + { + singleproxy["network"] = transproto; + singleproxy["ws-path"] = path; + singleproxy["ws-headers"]["Host"] = host; + } + else if(transproto == "kcp" || transproto == "h2" || transproto == "quic") + continue; + } + else if(type == "SSR" && clashR) + { + protocol = GetMember(json, "Protocol"); + protoparam = GetMember(json, "ProtocolParam"); + obfs = GetMember(json, "OBFS"); + obfsparam = GetMember(json, "OBFSParam"); + singleproxy["type"] = "ssr"; + singleproxy["cipher"] = method; + singleproxy["protocol"] = protocol; + singleproxy["protocolparam"] = protoparam; + singleproxy["obfs"] = obfs; + singleproxy["obfsparam"] = obfsparam; + } + else if(type == "Socks5") + { + singleproxy["type"] = "socks"; + singleproxy["username"] = username; + } + else if(type == "HTTP" || type == "HTTPS") + { + singleproxy["type"] = "http"; + singleproxy["username"] = username; + singleproxy["tls"] = type == "HTTPS"; + } + else + continue; + singleproxy["password"] = password; + singleproxy["name"] = remark; + singleproxy["server"] = hostname; + singleproxy["port"] = (unsigned short)stoi(port); + proxies.push_back(singleproxy); + nodelist.emplace_back(remark); + } + + yamlnode["Proxy"] = proxies; + std::string groupname; + /* + if(!overwrite_original_groups) + { + original_groups = yamlnode["Proxy Group"]; + for(unsigned int i = 0; i < original_groups.size(); i++) + { + groupname = original_groups[i]["name"].as(); + if(groupname == "Proxy" || groupname == "PROXY") + { + original_groups[i]["name"] = "Proxy"; + original_groups[i]["proxies"] = vectorToNode(nodelist); + break; + } + } + } + else + { + singlegroup["name"] = "Proxy"; + singlegroup["type"] = "select"; + singlegroup["proxies"] = vectorToNode(nodelist); + original_groups.push_back(singlegroup); + } + */ + + for(std::string &x : extra_proxy_group) + { + singlegroup.reset(); + eraseElements(filtered_nodelist); + replace_flag = false; + unsigned int rules_upper_bound = 0; + + vArray = split(x, "`"); + if(vArray.size() < 3) + continue; + + if(vArray[1] == "select") + { + rules_upper_bound = vArray.size(); + } + else if(vArray[1] == "url-test" || vArray[1] == "fallback" || vArray[1] == "load-balance") + { + if(vArray.size() < 5) + continue; + rules_upper_bound = vArray.size() - 2; + singlegroup["url"] = vArray[vArray.size() - 2]; + singlegroup["interval"] = stoi(vArray[vArray.size() - 1]); + } + else + continue; + + for(unsigned int i = 2; i < rules_upper_bound; i++) + { + if(vArray[i].find("[]") == 0) + { + filtered_nodelist.emplace_back(vArray[i].substr(2)); + } + else + { + for(std::string &y : nodelist) + { + if(regFind(y, vArray[i]) && std::find(filtered_nodelist.begin(), filtered_nodelist.end(), y) == filtered_nodelist.end()) + filtered_nodelist.emplace_back(y); + } + } + } + + if(!filtered_nodelist.size()) + filtered_nodelist.emplace_back("DIRECT"); + + singlegroup["name"] = vArray[0]; + singlegroup["type"] = vArray[1]; + singlegroup["proxies"] = vectorToNode(filtered_nodelist); + + for(unsigned int i = 0; i < original_groups.size(); i++) + { + if(original_groups[i]["name"].as() == vArray[0]) + { + original_groups[i] = singlegroup; + replace_flag = true; + break; + } + } + if(!replace_flag) + original_groups.push_back(singlegroup); + } + + yamlnode["Proxy Group"] = original_groups; + + rulesetToClash(yamlnode, ruleset_content_array); + + return to_string(yamlnode); +} diff --git a/subexport.h b/subexport.h new file mode 100644 index 0000000..3dc9565 --- /dev/null +++ b/subexport.h @@ -0,0 +1,12 @@ +#ifndef SUBEXPORT_H_INCLUDED +#define SUBEXPORT_H_INCLUDED + +#include + +struct ruleset_content +{ + std::string rule_group; + std::string rule_content; +}; + +#endif // SUBEXPORT_H_INCLUDED diff --git a/webget.cpp b/webget.cpp new file mode 100644 index 0000000..91bfb2c --- /dev/null +++ b/webget.cpp @@ -0,0 +1,57 @@ +#include +#include + +#include + +#include "webget.h" + +std::string user_agent_str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"; + +static int writer(char *data, size_t size, size_t nmemb, std::string *writerData) +{ + if(writerData == NULL) + return 0; + + writerData->append(data, size*nmemb); + + return size * nmemb; +} + +std::string curlGet(std::string url, std::string proxy) +{ + CURL *curl_handle; + std::string data; + + curl_global_init(CURL_GLOBAL_ALL); + + curl_handle = curl_easy_init(); + curl_easy_setopt(curl_handle, CURLOPT_URL, url.data()); + curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0L); + curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 10L); + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, user_agent_str.data()); + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writer); + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &data); + if(proxy != "") + curl_easy_setopt(curl_handle, CURLOPT_PROXY, proxy.data()); + + curl_easy_perform(curl_handle); + curl_easy_cleanup(curl_handle); + + return data; +} + +std::string buildSocks5ProxyString(std::string addr, int port, std::string username, std::string password) +{ + std::string authstr = username != "" && password != "" ? username + ":" + password + "@" : ""; + std::string proxystr = "socks5://" + authstr + addr + ":" + std::__cxx11::to_string(port); + return proxystr; +} + +std::string webGet(std::string url, std::string proxy) +{ + return curlGet(url, proxy); +} diff --git a/webget.h b/webget.h new file mode 100644 index 0000000..1fa659b --- /dev/null +++ b/webget.h @@ -0,0 +1,18 @@ +#ifndef WEBGET_H_INCLUDED +#define WEBGET_H_INCLUDED + +#include + +#ifdef _WIN32 +#include +#endif // _WIN32 + +#include "misc.h" + +std::string webGet(std::string url, std::string proxy = ""); +std::string httpGet(std::string host, std::string addr, std::string uri); +std::string httpsGet(std::string host, std::string addr, std::string uri); +long curlPost(std::string url, std::string data, std::string proxy); +std::string buildSocks5ProxyString(std::string addr, int port, std::string username, std::string password); + +#endif // WEBGET_H_INCLUDED diff --git a/webserver.cpp b/webserver.cpp new file mode 100644 index 0000000..1454fb2 --- /dev/null +++ b/webserver.cpp @@ -0,0 +1,376 @@ +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "socket.h" +#include "webserver.h" + +typedef std::vector string_array; + +struct responseRoute +{ + std::string method; + std::string path; + std::string content_type; + response_callback rc; +}; + +std::vector responses; + +//for use of multi-thread socket test +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 sendall(SOCKET sock, std::string data) +{ + unsigned int total = 0, bytesleft = data.size(); + int sent = 0; + const char* datastr = data.data(); + while(total < bytesleft) + { + sent = send(sock, datastr + total, bytesleft, 0); + if(sent < 0) + { + std::cerr< 2) + { + wrong_req(client_sock); + goto end; + } + else if(vArray.size() > 1) + { + uri = vArray[0]; + args = vArray[1]; + } + else + uri = arguments; + + if(strcmp(command, "POST") == 0) + { + if(request.find("\r\n\r\n") != request.npos) + postdata = request.substr(request.find("\r\n\r\n") + 4); + } + else if(strcmp(command, "OPTIONS") == 0) + { + serve_options(client_sock); + goto end; + } + + for(std::vector::iterator iter = responses.begin(); iter != responses.end(); iter++) + { + if(iter->method.compare(command) == 0 && iter->path == uri) + { + response_callback &rc = iter->rc; + serve_content(client_sock, iter->content_type, rc(args, postdata)); + goto end; + } + } + file_not_found(uri, client_sock); + +end: + std::cerr<<"worker stop"<listen_address, request; + int port = args->port, max_conn = args->max_conn, max_workers = args->max_workers, numbytes, worker_index = 0; + socklen_t sock_size = sizeof(struct sockaddr_in); + char buf[BUFSIZ]; + struct sockaddr_in user_socket, server_addr; + SOCKET acc_socket; + int server_socket, fail_counter = 0; + server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + std::thread workers[max_workers]; + + if (server_socket == -1) + { + //log socket error + std::cerr<<"socket build error!"< max_send_failure) + break; + continue; + } + else + { + break; + } + } + request = ""; + while(true) //receive the complete request + { + numbytes = recv(acc_socket, buf, BUFSIZ - 1, 0); + if(numbytes > 0) //received + request.append(buf); + if(numbytes < 0) + { + if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) + { + continue; + } + else + { + break; + } + } + if(numbytes == 0) + break; + } + + //handle_req(buf, acc_socket); + + while(safe_read_working() >= max_workers) + { + sleep(10); + if(safe_read_server_exit_flag()) + break; + } + while(workers[worker_index].get_id() != std::thread::id()) + { + worker_index++; + } + workers[worker_index] = std::thread(handle_req, request, acc_socket); + workers[worker_index].detach(); + worker_index++; + if(worker_index > max_workers) + worker_index = 0; + } + return 0; +} diff --git a/webserver.h b/webserver.h new file mode 100644 index 0000000..eebd4d8 --- /dev/null +++ b/webserver.h @@ -0,0 +1,20 @@ +#ifndef WEBSERVER_H_INCLUDED +#define WEBSERVER_H_INCLUDED + +typedef std::string (*response_callback)(std::string, std::string); //process arguments and POST data and return served-content + +#define RESPONSE_CALLBACK_ARGS std::string argument, std::string postdata + +struct listener_args +{ + std::string listen_address; + int port; + int max_conn; + int max_workers; +}; + +void append_response(std::string type, std::string request, std::string content_type, response_callback response); +int start_web_server(void *argv); +int start_web_server_multi(void *argv); + +#endif // WEBSERVER_H_INCLUDED diff --git a/webserver_libevent.cpp b/webserver_libevent.cpp new file mode 100644 index 0000000..b43822e --- /dev/null +++ b/webserver_libevent.cpp @@ -0,0 +1,221 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "misc.h" +#include "webserver.h" +#include "socket.h" + +struct responseRoute +{ + std::string method; + std::string path; + std::string content_type; + response_callback rc; +}; + +std::vector responses; + +static inline int process_request(const char *method_str, std::string uri, std::string &postdata, std::string &content_type, std::string &return_data) +{ + std::string path, arguments; + //std::cerr << "handle_cmd: " << method_str << std::endl << "handle_uri: " << uri << std::endl; + + if(strFind(uri, "?")) + { + path = uri.substr(0, uri.find("?")); + arguments = uri.substr(uri.find("?") + 1); + } + else + path = uri; + + for(responseRoute &x : responses) + { + if(strcmp(method_str, "OPTIONS") == 0 && x.method == postdata && x.path == path) + { + return 1; + } + else if(x.method.compare(method_str) == 0 && x.path == path) + { + response_callback &rc = x.rc; + return_data = rc(arguments, postdata); + content_type = x.content_type; + return 0; + } + } + + return -1; +} + +void OnReq(evhttp_request *req, void *args) +{ + const char *req_content_type = evhttp_find_header(req->input_headers, "Content-Type"), *req_ac_method = evhttp_find_header(req->input_headers, "Access-Control-Request-Method"); + const char *req_method = req_ac_method == NULL ? EVBUFFER_LENGTH(req->input_buffer) == 0 ? "GET" : "POST" : "OPTIONS", *uri = evhttp_request_get_uri(req); + int retVal; + std::string postdata, content_type, return_data; + + if(EVBUFFER_LENGTH(req->input_buffer) != 0) + { + postdata.assign((char *)EVBUFFER_DATA(req->input_buffer), EVBUFFER_LENGTH(req->input_buffer)); + if(req_content_type != NULL && strcmp(req_content_type, "application/x-www-form-urlencoded") == 0) + postdata = UrlDecode(postdata); + } + else if(req_ac_method != NULL) + { + postdata.assign(req_ac_method); + } + + retVal = process_request(req_method, uri, postdata, content_type, return_data); + + auto *OutBuf = evhttp_request_get_output_buffer(req); + if (!OutBuf) + return; + + switch(retVal) + { + case 1: //found OPTIONS + evhttp_add_header(req->output_headers, "Access-Control-Allow-Origin", "*"); + evhttp_add_header(req->output_headers, "Access-Control-Allow-Headers", "*"); + evhttp_send_reply(req, HTTP_OK, "", NULL); + return; + break; + case 0: //found normal + if(content_type.size()) + { + if(content_type == "REDIRECT") + { + evhttp_add_header(req->output_headers, "Location", return_data.c_str()); + evhttp_send_reply(req, HTTP_MOVETEMP, "", NULL); + return; + } + else + evhttp_add_header(req->output_headers, "Content-Type", content_type.c_str()); + } + evhttp_add_header(req->output_headers, "Access-Control-Allow-Origin", "*"); + evhttp_add_header(req->output_headers, "Connection", "close"); + evbuffer_add(OutBuf, return_data.data(), return_data.size()); + evhttp_send_reply(req, HTTP_OK, "", OutBuf); + break; + case -1: //not found + evhttp_send_error(req, HTTP_NOTFOUND, "Resource not found"); + break; + default: //undefined behavior + evhttp_send_error(req, HTTP_INTERNAL, ""); + } +} + +int start_web_server(void *argv) +{ + struct listener_args *args = (listener_args*)argv; + std::string listen_address = args->listen_address; + int port = args->port; + if (!event_init()) + { + std::cerr << "Failed to init libevent." << std::endl; + return -1; + } + const char *SrvAddress = listen_address.c_str(); + std::uint16_t SrvPort = port; + std::unique_ptr Server(evhttp_start(SrvAddress, SrvPort), &evhttp_free); + if (!Server) + { + std::cerr << "Failed to init http server." << std::endl; + return -1; + } + + evhttp_set_allowed_methods(Server.get(), EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_OPTIONS); + evhttp_set_gencb(Server.get(), OnReq, nullptr); + if (event_dispatch() == -1) + { + std::cerr << "Failed to run message loop." << std::endl; + return -1; + } + + return 0; +} + +void* httpserver_dispatch(void *arg) +{ + event_base_dispatch((struct event_base*)arg); + return NULL; +} + +int httpserver_bindsocket(std::string listen_address, int listen_port, int backlog) +{ + int ret; + SOCKET nfd; + nfd = socket(AF_INET, SOCK_STREAM, 0); + if (nfd < 0) + return -1; + + int one = 1; + ret = setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int)); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(listen_address.data()); + addr.sin_port = htons(listen_port); + + ret = bind(nfd, (struct sockaddr*)&addr, sizeof(addr)); + if (ret < 0) + return -1; + ret = listen(nfd, backlog); + if (ret < 0) + return -1; + + unsigned long ul = 1; + ioctlsocket(nfd, FIONBIO, &ul); //set to non-blocking mode + + return nfd; +} + +int start_web_server_multi(void *argv) +{ + struct listener_args *args = (listener_args*)argv; + std::string listen_address = args->listen_address; + int port = args->port, nthreads = args->max_workers; + int i, ret; + + int nfd = httpserver_bindsocket(listen_address, port, args->max_conn); + if (nfd < 0) + return -1; + + pthread_t ths[nthreads]; + for (i = 0; i < nthreads; i++) + { + struct event_base *base = event_init(); + if (base == NULL) + return -1; + struct evhttp *httpd = evhttp_new(base); + if (httpd == NULL) + return -1; + ret = evhttp_accept_socket(httpd, nfd); + if (ret != 0) + return -1; + + 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); + if (ret != 0) + return -1; + } + + return 0; +} + +void append_response(std::string type, std::string request, std::string content_type, response_callback response) +{ + responseRoute rr; + rr.method = type; + rr.path = request; + rr.content_type = content_type; + rr.rc = response; + responses.emplace_back(rr); +} diff --git a/yamlcpp_extra.h b/yamlcpp_extra.h new file mode 100644 index 0000000..7162ee8 --- /dev/null +++ b/yamlcpp_extra.h @@ -0,0 +1,14 @@ +#include +#include + +#include + +#include "misc.h" + +YAML::Node vectorToNode(string_array data) +{ + YAML::Node node; + for(std::string &x : data) + node.push_back(x); + return node; +}